Shahzad Bhatti

October 25, 2008

My gripes about REST services

Filed under: REST — admin @ 11:17 am

I love REST style services because of their simplicity and ease of testing. I have discussed benefits of REST earlier. I have used a number of distributed technologies over seventeen years such as LU6.2 (CICS) for mainframes, BSD Sockets, RPC, CORBA, RMI, JINI, Messaging Middlewares, SOAP, etc. In most of those technologies, you had to use special libraries to interact with the server. I worked in some organizations where I saw real dependency hell or jar hell, where I had to import dozens of client jars from different groups to talk to those services. REST, on the other hand only relies on http (and security) libraries.

I first wrote REST style service in late 90s before I knew about the REST term. At the time, I worked as a consultant for government DOTs and built CORBA based system to provide traffic data to media agencies. However, people were scraping our website for the data so I built an XML over HTTP service to download the data with some credentials. I think a lot of people used simplicity of HTTP to build similar services. And many of them didn’t understand REST as put forth by Roy Fielding. Over past few years, a lot of people are promoting real style of REST such as Sam Ruby, Stefan Tilkov, Steve Vinosky and Roy Fielding himself. At the same time, they are chastising people who diverge from their vision.

I have tried building REST style services over last few years and recently I have started building new services that will be used for entire organization. As, these services will need to support large number of transactions, performance and scalability are critical. Also, these services need to support batch of requests. In my older blog, I discussed commandments for writing service and wrote about importance of batch requests for scalability. That requirement changes a few things, for example instead of taking advantage of request parameters in HTTP, I had to use XML for input request and had to use XML for response. Though, this style is suitable for POST or PUT where you are expecting to read request as a file but is unnatural for GET types.

Another tenant of REST style services is resource. In this style, you interact with the service similar to how users interact with a web site, i.e., you click on links to go to another page, which returns more links and so on. However, this style in service adds network communication. For example, in one of the service for workflow I had to return active tasks for a particular workflow. In true REST style, I would have to return a hyperlink for each task instead of contents of task and the client would have to ask server for task content by hitting the resource for the task. As, you might guess this adds significant network latency so I am being practical instead of purest and as a result, I am returning task contents. Also, the sevice allows you to pass requests for multiple workfows and returns a single response for all workflows.

I used similar style when using messaging middlewares that allowed serving batches of requests in a single message. I found messaging middlewares offered more flexible options, e.g. you can design an aggregator service that waits for a few seconds for incoming requests and then puts them in a single request to another service that serve them. These kind of batch services are integral for building scalable systems. I have discussed some of these limitations in earlier blog, especially its lack of push based architecture. Though there are some workaround for push such as long-lived http connection that are difficult to use behind firewall, comet style or reverse ajax based communication, which is limited and more recently reverse http, which is too new to apply in real applications. Perhaps, messaging standards like XMPP can fill this gap.

I find that IT industry is largely driven by a single minded attitude where every new technology, language or process is adopted by bandwagon of people who just repeat each other’s words without understanding. For example, I have seen similar attitude from agile folks, folks from object oriented programming, aspect oriented programming, metaprogramming or dynamic programming, design patterns, etc. In the end, I believe you have to be practical instead of purest and as always answer to every question in IT is “it depends”, i.e., there is no single universal solution.

October 22, 2008

Developing REST based services using JSR 311

Filed under: Java — admin @ 1:28 pm

Recently, I had to write a few services using REST style in Java. Though I have developed such services in past either using Java Servlet APIs, but I wanted to find something better. I had found writing REST style services in Ruby on Rails a breeze and I wanted something as testable and easy to configure. I found a new JSR 311 that does exactly that. Similar to EJB 3.0 and Servlet 3.0 trend, it allows you to write REST services using annotations. I found an open source project that implements JSR 311 and just released 1.0. I found most of the documentation was Maven and Glassfish driven and I wanted to simply try on Tomcat and Ant so here is how I did it:

Download and Install

First, download following jar libraries (you can see that I am using jars from maven repository because Jersey’s wiki was missing jars or pointing to old version):

Developing

My application used models to describe business object, DAOs for database access and I didn’t want to pollute my business objects with REST annotations so I created two new packages for resources and services. Here is a simple example that follows this separation of concerns:

Business Objects (Model)

The model simply consists of a contact class that stores contact information for a person.

 
 package rest;
 
 public class Contact {
     private final String name;
     private final String email;
     private final String address;
 
     public Contact(final String name, final String email, final String address) {
         this.name = name;
         this.email = email;
         this.address = address;
     }
 
 
     public String getName() {
         return name;
     }
 
     public String getEmail() {
         return email;
     }
 
     public String getAddress() {
         return address;
     }
 }
 

Data Access Layer

The data access layer simply uses a hashmap for storing and accessing these contacts, e.g.

 
 package rest;
 
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 
 public class ContactDao {
     private static Map repository = new HashMap();
 
     public boolean save(Contact c) {
         boolean created = repository.get(c.getName()) != null;
         repository.put(c.getName(), c);
         return created;
     }
 
     public boolean delete(String name) {
         return repository.remove(name) != null;
     }
 
     public Contact get(String name) {
         return repository.get(name);
     }
 
     public Collection getAll() {
         return repository.values();
     }
 }
 
 

Resources

For resources, I defined ContactResource that adds XML annotations to convert Contact into XML and ContactsResponse for returning complete XML response, e.g.

 
 package rest;
 import javax.ws.rs.core.UriInfo;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
 import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
                                                                                                                                                       
 
 @XmlAccessorType(XmlAccessType.PROPERTY)
 @XmlRootElement(name = "Contact")
 public class ContactResource {
     private UriInfo uriInfo;
     private Contact contact;
 
     public ContactResource(final UriInfo uriInfo, final String name, final String email, final String address) {
         this.uriInfo = uriInfo;
         this.contact = new Contact(name, email, address);
     }
 
 
     public ContactResource(final Contact contact) {
         this.contact = contact;
     }
 
 
     ContactResource() {
     }
 
 
     public JSONObject toJson() throws JSONException {
         return new JSONObject()
             .put("name", contact.getName())
             .put("email", contact.getEmail())
             .put("address",contact.getAddress());
     }
 
     @XmlElement(name = "Name")
     public String getName() {
         return contact.getName();
     }
 
     @XmlElement(name = "Email")
     public String getEmail() {
         return contact.getEmail();
     }
 
     @XmlElement(name = "Address")
     public String getAddress() {
         return contact.getAddress();
     }
 }
 
 
 

 
 package rest;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
 
 
 @XmlAccessorType(XmlAccessType.PROPERTY)
 @XmlRootElement(name = "ContactsResponse")
 public class ContactsResponse {
     private String uri;
     private String status;
     private Collection contacts;
 
     public ContactsResponse(String uri, String status, Collection contacts) {
         this.uri = uri;
         this.status = status;
         this.contacts = new ArrayList();
         for (Contact contact : contacts) {
             this.contacts.add(new ContactResource(contact));
         }
     }
 
     public ContactsResponse(String uri, String status, Contact contact) {
         this(uri, status, contact == null ? new ArrayList() : Collections.singleton(contact));
     }
 
     ContactsResponse() {
     }
 
     @XmlElement(name = "Uri")
     public String getUri() {
         return uri;
     }
     public void setUri(String uri) {
         this.uri = uri;
     }
     @XmlElement(name = "Status")
     public String getStatus() {
         return status;
     }
     public void setStatus(String status) {
         this.status = status;
     }
 
     @XmlElement(name = "Contacts")
     public Collection getContactResources() {
         return contacts;
     }
     public void setContactResources(Collection contacts) {
         this.contacts = contacts;
     }
 }
 
 

Service

Here is the meat of JSR 311 that defines annotations for the REST based web service, i.e.,

 
 package rest;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.Collection;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.FormParam;
 import javax.ws.rs.GET;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Request;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 
 import org.codehaus.jettison.json.JSONArray;
 import org.codehaus.jettison.json.JSONException;
 import org.springframework.context.annotation.Scope;
 
 import com.sun.jersey.api.spring.Autowire;
 
 @Path("/contacts/")
 @Produces( { "application/json", "application/xml" })
 @Consumes( { "application/json", "application/xml" })
 @Scope("singleton")
 @Autowire
 public class ContactService {
     private final ContactDao contactDao;
     @Context UriInfo uriInfo;
     @Context Request request;
 
     public ContactService(ContactDao dao) {
         this.contactDao = dao;
     }
 
     public ContactService() {
         this(new ContactDao()); // this will be injected in real-app
     }
 
     /**
      * create contact
      */
     @PUT
     @Consumes("*/*")
     @Produces("application/xml")
     @Path("{name}")
     public Response createcontact(
             @PathParam("name") String name,
             @FormParam("email") String email,
             @FormParam("address") String address) {
         Contact contact = new Contact(name, email, address);
         final boolean newRecord = contactDao.save(contact);
         if (newRecord) {
             try {
                 URI uri = uriInfo != null ? uriInfo.getAbsolutePath()
                         : new URI("/contacts/");
                 return Response.created(uri).build();
             } catch (URISyntaxException e) {
                 throw new RuntimeException("Failed to create uri", e);
             }
         } else {
             return Response.noContent().build();
         }
     }
 
     /**
      * deletes contact 
      * 
      */
     @DELETE
     @Consumes("*/*")
     @Path("{name}")
     public Response deletecontact(@PathParam("name") String name) {
         boolean deleted = contactDao.delete(name);
         if (deleted) {
             return Response.ok().build();
         } else {
             return Response.status(404).build();
         }
     }
 
     /**
      * @return contact in XML format
      */
     @GET
     @Consumes({"text/xml", "application/xml"})
     @Produces("application/xml")
     @Path("{name}")
     public ContactsResponse getcontactByXml(
             @PathParam("name") String name) {
         Contact contact = contactDao.get(name);
         String uri = uriInfo != null ? uriInfo.getAbsolutePath().toString() : "/contacts/";
         return new ContactsResponse(uri, "success", contact);
     }
 
     /**
      * @return contact in JSON format
      */
     @GET
     @Consumes("application/json")
     @Produces("application/json")
     @Path("{name}")
     public JSONArray getcontactByJson(@PathParam("name") String name) throws JSONException {
         Contact contact = contactDao.get(name);
         JSONArray arr = new JSONArray();
         arr.put(new ContactResource(contact).toJson());
         return arr;
     }
 
     /**
      * @return all contacts in XML format
      */
     @GET
     @Consumes({"text/xml", "application/xml"})
     @Produces("application/xml")
     public ContactsResponse getAllByXml() {
         Collection contacts = contactDao.getAll();
         String uri = uriInfo != null ? uriInfo.getAbsolutePath().toString() : "/contacts/";
         return new ContactsResponse(uri, "success", contacts);
     }
 
     /**
      * @return contacts in JSON format
      */
     @GET
     @Consumes("application/json")
     @Produces("application/json")
     public JSONArray getAllByJson() throws JSONException {
         Collection contacts = contactDao.getAll();
         JSONArray arr = new JSONArray();
         for (Contact contact : contacts) {
             arr.put(new ContactResource(contact).toJson());
         }
         return arr;
     }
 }
 
 

A few things to note:

  • @Path defines the URI used for accessing the service
  • I am using @PUT to store contacts (as the user is creating new URI as opposed to @POST where the application uses same URI). Also, I don’t have any method for update (which uses PUT) as I already am using PUT and create method simply updates the contact if it already exist.
  • @PathParam is retrieved from the URI itself, e.g. /contacts/myname
  • @FormParam is retrieved from POST form submission
  • I can use the same URI and return different type of data based on Content-Type, e.g. when user sets it to application/xml or text/xml I return XML content and when user sets it to application/json I return JSON format.
  • To return list of contacts I skip the name and simply use /contacts/

Servlet Configuration

I added servlet to handle REST requests to web.xml, e.g.

     <servlet>
         <servlet-name>RestServlet</servlet-name>
         <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
         <init-param>
             <param-name>com.sun.jersey.config.feature.Redirect</param-name>
             <param-value>true</param-value>
         </init-param>
         <init-param>
             <param-name>com.sun.jersey.config.feature.ImplicitViewables</param-name>
             <param-value>true</param-value>
         </init-param>
         <init-param>
             <param-name>com.sun.jersey.config.property.packages</param-name>
             <param-value>rest</param-value>
         </init-param>
         <load-on-startup>1</load-on-startup>
     </servlet>
     <servlet-mapping>
         <servlet-name>RestServlet</servlet-name>
         <url-pattern>/svc/*</url-pattern>
     </servlet-mapping>
 

I used Spring to inject DAOs in real application but if you don’t need it then replace com.sun.jersey.spi.spring.container.servlet.SpringServlet with com.sun.jersey.spi.container.servlet.ServletContainer.

Also note that com.sun.jersey.config.property.packages defines package name of Java classes that defines service classes.

Deploying

I am assuming you already know how to package a war file and deploy it to application server such as Tomcat.

Testing it

Unit Testing it

A big advantage of JSR 311 is ease of test, e.g. here is a sample unit test:

 
 package rest;
 import javax.ws.rs.core.Response;
 
 import junit.framework.TestCase;
 import org.codehaus.jettison.json.JSONArray;
 import org.codehaus.jettison.json.JSONObject;
 
 import com.sun.jersey.api.NotFoundException;
 
 public class ContactServiceTest extends TestCase {
     private ContactService service;
 
     @Override
     protected void setUp() throws Exception {
         service = new ContactService();
     }
 
     public void testCreateContactWithGetContactByXml() {
         final String name = "shahbhat";
         final String email = "shahbhat@myhost";
         final String address = "shahbhat address ";
 
         Response response = service.createContact(name, email, address);
         assertEquals(201, response.getStatus());
         assertNull(response.getEntity());
 
         // recreate the same mapping and it should return no content
         response = service.createContact(name, email, address);
         assertEquals(204, response.getStatus());
         assertNull(response.getEntity());
 
         ContactsResponse contactResponse = service.getContactByXml(name);
         assertEquals(1, contactResponse.getContactResources().size());
         ContactResource contactResource = contactResponse.getContactResources().iterator().next();
         assertEquals(name, contactResource.getName());
         assertEquals(email, contactResource.getEmail());
         assertEquals(address, contactResource.getAddress());
     }
 
     public void testCreateContactWithGetContactByJson() throws Exception {
         final String name = "shahbhat";
         final String email = "shahbhat@myhost";
         final String address = "shahbhat address ";
 
         Response response = service.createContact(name, email, address);
         assertEquals(201, response.getStatus());
         assertNull(response.getEntity());
 
         JSONArray jsonArray = service.getContactByJson(name);
         assertEquals(1, jsonArray.length());
         JSONObject json = jsonArray.getJSONObject(0);
         assertEquals(name, json.getString("name"));
         assertEquals(email, json.getString("email"));
         assertEquals(address, json.getString("address"));
     }
 
     public void testDeleteContact() {
         final String name = "shahbhat";
         final String email = "shahbhat@myhost";
         final String address = "shahbhat address ";
 
         Response response = service.createContact(name, email, address);
         assertEquals(201, response.getStatus());
         assertNull(response.getEntity());
 
         ContactsResponse contactResponse = service.getContactByXml(name);
         assertEquals(1, contactResponse.getContactResources().size());
         ContactResource contactResource = contactResponse.getContactResources().iterator().next();
         assertEquals(name, contactResource.getName());
         assertEquals(email, contactResource.getEmail());
         assertEquals(address, contactResource.getAddress());
 
         response = service.deleteContact(name);
         assertEquals(200, response.getStatus());
 
         contactResponse = service.getContactByXml(name);
         assertEquals(0, contactResponse.getContactResources().size());
 
         //
         response = service.deleteContact(name);
         assertEquals(404, response.getStatus());
 
     }
 
     public void testGetAllContactByXml() {
         service.createContact("shahbhat", "shahbhat email", "shahbhat address");
         service.createContact("bill", "bill email", "bill address");
 
         ContactsResponse contactResponse = service.getAllByXml();
         assertEquals(2, contactResponse.getContactResources().size());
         for (ContactResource contactResource : contactResponse.getContactResources()) {
             if ("shahbhat".equals(contactResource.getName())) {
                 assertEquals("shahbhat email", contactResource.getEmail());
                 assertEquals("shahbhat address", contactResource.getAddress());
             } else if ("bill".equals(contactResource.getName())) {
                 assertEquals("bill email", contactResource.getEmail());
                 assertEquals("bill address", contactResource.getAddress());
             } else {
                 fail("unknown contact " + contactResource);
             }
         }
 
         service.deleteContact("shahbhat");
         service.deleteContact("bill");
 
         contactResponse = service.getAllByXml();
         assertEquals(0, contactResponse.getContactResources().size());
     }
 
 
     public void testGetAllContactByJson() throws Exception {
         service.createContact("shahbhat", "shahbhat email", "shahbhat address");
         service.createContact("bill", "bill email", "bill address");
 
         JSONArray jsonArray = service.getAllByJson();
         assertEquals(2, jsonArray.length());
 
         for (int i=0; i<2; i++) {
             JSONObject json = jsonArray.getJSONObject(i);
             if ("shahbhat".equals(json.getString("name"))) {
                 assertEquals("shahbhat email", json.getString("email"));
                 assertEquals("shahbhat address", json.getString("address"));
             } else if ("bill".equals(json.getString("name"))) {
                 assertEquals("bill email", json.getString("email"));
                 assertEquals("bill address", json.getString("address"));
             } else {
                 fail("unknown contact " + json);
             }
         }
         service.deleteContact("shahbhat");
         service.deleteContact("bill");
 
         jsonArray = service.getAllByJson();
         assertEquals(0, jsonArray.length());
     }
 }
 

Functional Testing it

Once deploy, you can use curl to functionally test it (though there are other automated tools available as well), e.g

Creating Contact

 curl -X PUT -d "email=myemail&address=myaddress"  http://shahbhat.desktop:8080/svc/contacts/bhatti
 

It will create a contact and to retrieve it, use

 curl http://shahbhat.desktop:8080/svc/contacts/bhatti
 

It should return

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?><ContactsResponse><Contacts><Address>myaddress</Address><Email>myemail</Email><Name>bhatti</Name></Contacts><Status>success</Status><Uri>http://shahbhat.desktop:8080/svc/contacts/bhatti</Uri></ContactsResponse>
 

To get JSON format use

 curl --header "Content-Type: application/json" http://shahbhat.desktop:8080/svc/contacts/bhatti
 

and it should return

 [{"name":"bhatti","email":"myemail","address":"myaddress"}]
 

You can create another contact e.g.

 curl -d "email=billemail&address=billaddress"  http://shahbhat.desktop:8080/svc/contacts/bill
 

Now to get all contacts use

 curl http://shahbhat.desktop:8080/svc/contacts/
 

and it will return

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?><ContactsResponse><Contacts><Address>myaddress</Address><Email>myemail</Email><Name>bhatti</Name></Contacts><Contacts><Address>billaddress</Address><Email>billemail</Email><Name>bill</Name></Contacts><Status>success</Status><Uri>http://shahbhat.desktop:8080/svc/contacts/</Uri></ContactsResponse>
 

And to get JSON format use

 curl --header "Content-Type: application/json" http://shahbhat.desktop:8080/svc/contacts/
 

which will return

 [{"name":"bhatti","email":"myemail","address":"myaddress"},{"name":"bill","email":"billemail","address":"billaddress"}]
 

Conclusion

I found this approach is easily testable with standard unit test and easy to develop. Though, there are few glitches, e.g. @QueryParam only works with GET and if you are POSTing to something like /uri?x=yy then you won't see query parameters. But, overall I am happy with the outcome and will continue to use this framework.

October 18, 2008

Concurrency Constructs

Filed under: Computing — admin @ 11:43 am

With the proliferation of multi-cores, concurrency has been a hot topic for past few years. I described a few ways to tackle concurrency in my blog earlier this year. As I mentioned in my blog, this problem is nothing for scientific and research community. Also, many languages have had devised numerous constructs to tackle these abstractions and other languages are adding support for concurency. I will go over some of these abstractions here:

Processes

All modern operating systems support preemptive multitasking and processes have been simple way to add concurrency. For example, this technique is used by Apache web server that launches multiple processes and serve thousands of clients at a time. There are also a number of system primitives for inter-process communication such as shared memory, sockets, pipes and other forms of middlewares and peer to peer technology. This technique is specially suitable for many scripting languages that don’t have concurrency support such as Perl, Ruby, CPython, etc. Despite their scripting nature, these languages are highly productive. For example, much of Amazon’s retail website is built using Perl/Mason and uses multiple processes served by FastCGI for handling concurrent requests. Though, Ruby and Python support green threads, but are not designed for concurrency. For example, Global Interpreter Lock (GIL) in Python only allows one thread to execute at a time. Similarly, Ruby has Global VM lock that also allows one thread to execute at a time. These limitations have also effected kind of applications you can built. For example, one of criticism of Ruby on Rails framework has been its lack of concurrency. Though, there have been a number of solutions that tackle this problem by multi-processing such as clusters of mongrel, FastCGI, etc.

This model is also used by Fork/Join, Map/Reduce, Master-Slave and Leader/Follower style of parallel programming, where the master process creates work and distributes work to workers, who work on it. There are a plenty of libraries and frameworks available for this such as Globus, Hadoop, MPI/MPL, PVM and Fork/Join in Java 7.

Kernel Threads

Many languages support kernel threads that are mapped to lightweight processes (LWP) and scheduled by the operating systems. The operating system context switches between threads using time-slicing that give perception of concurrency. Posix compliant operating systems offer a number of solutions for inter-thread communication and synchronization such as mutex, semaphores, condition variables. Many languages offer support for high level synchronization such as concurrent library in Java.

Green Threads/Fibers

As opposed to native threads, green threads run in user space and scheduled by using yield to allow other thread/fiber to execute. As user threads or fibers rely on collaboration, they are easily subject to starvation. Some languages encapsulate blocking I/O with nonblocking I/O and automatically yield fiber when they make blocking call. Effective use of fibers can help applications scale more than multi-processing or multi-threading, which are generally limited by the system resources. For example, in a performance comparison between Apache and Yaws, where latter was built in Erlang that uses user processes was able to scale upto 80,000 concurrent connections whereas Apache died at around 4000 connections. Ruby 1.9 has just added support for fibers, which can be used to build streams, e.g.

 fib = Fiber.new do  
    x, y = 0, 1 
    loop do  
     Fiber.yield y 
     x,y = y,x+y 
    end 
   end 
   20.times { puts fib.resume } 
 

Streams

Streams are sort of iterators over infinite lists and often used in functional languages, though many imperative programming languages now support them to create infinite lists. You can find a number of examples of Strams in languages like Groovy, Scala, Haskell, etc. Python offers similar capability via generators that contain yield keyword, which causes compiler to suspend generator until next() method of generator is called. For example,

 def generate_ints(N):
     for i in range(N):
         yield i
 
 >>> gen = generate_ints(2)
 >>> gen.next()
 >>> gen.next()
 

Coroutines

Coroutines are similar user threads and unlike subroutines, they have multiple entry and exit points. They are often built using contiuations or generators. In C, setjmp and longjmp can be used to implement coroutine. Ruby 1.9 added support for fibers that are more accurately semi-coroutines [pp 167].

Continuation

Continuation work like saving game at a checkpoint and resuming it. Traditionaly goto were used to implement continuations, though a number of languages have native support for continuations such as Scheme, Smalltalk, Ruby (callcc), Scala, C (setjmp/longjmp), etc. Though, they are not without problems but Seaside web framework based on Smalltalk has shown innovative way to write web applications using continuation passing style.

Actor model

I was introduced to actor model in mid mid 90s when working on graduate and post-graduate work. An actor has its own thread of execution with a mailbox. It communicates to other actors by sending messages that are delivered to its mailbox. Erlang, a language designed for concurrency, is based on actor model and more recently Scala has adopted actor model as well. When I worked for high performance computing (HPC) area in 90s, I used SGI systems that were built using NUMA based shared memory and messaging passing systems/libraries such as MPI, MPL, etc. I found message passing systems were much more scalable than shared memory, so I believe this style of programming will have best chance of succeeding. Though, I admit I found converting algorithms into message passing style is not easy.

Reactive or Event driven style

In reactive or event driven style, systems communicate by sending or listening on events. It’s sort of flip-style of threading, instead of creating new thread for each new concurrent task, it uses a fixed number of threads that cooperate. It is more scalable than multi-threading (kernel) as native threads are limited by available resources and context switching is expensive. For example, event-driven Mongrel server is much more scalable than Mogrel server. A number of J2EE application servers such as Glassfish, Jetty and Tomcat 6 have adopted Grizzly framework that uses asynchronous I/O to implement reactive style servers.

Software Transactional Memory

It’s difficult to write correct program using shared memory and as it requires proper locking of shared data and special attention to thread starvation and deadlock issues. A number of languages like Clojure, Haskell and Fortress have added support for software transactional memory that provide implicit locking through transactions. I have not used this style of programming but it seems to make writing concurrent applications easy. Though, I believe scalability with shared memory may only help with systems upto a few cores or processors.

TupleSpace based model

In tuple space, processes communicate to each other by storing messages in tuple spaces. The tuple space provides simple APIs like get, put, read and eval. Where get/read are blocking operations to implement dataflow based application and eval creates a new process to execute a task and store result in the tuple space. I built a similar system called JavaNOW, though there are a number of open source and commercial frameworks availeble such as JavaSpaces, GigaSpaces, Blitz.

Declarative concurrency

I heard recently Anders Hejlsberg and Guy Steele talked about concurrency and Anders suggested declarative concurrency where the programmer indicates parts of the applications that can be run concurrently. In a way, it is similar to compiler based parallelism used in High performance Fortran or Parallel Fortran that used data flow analysis to create parallel applications.

In nutshell, I find that more and more languages are adding constructs and frameworks to address concurrency and we will have to get used to these constructs to write programs that are future proof.

October 14, 2008

Observe, Orient, Decide and Act

Filed under: Methodologies — admin @ 8:49 pm

I have heard agile evangilists talk about influence of John Boyd on agile methodologies. I have also read about his story in books like Release It and more recently in Simple Architectures for Complex Enterprises, which I am currently reading. You can read more about Boyd’s background from wikipedia link above but he came up with iterative cycle of: observe, orient, decide and act (OODA). One of key finding he made was that shorter feedback or iteration loop of OODA with low quality was better than longer or tiring cycle of OODA with high quality. Despite the fact that everyone calls his/her organization agile, this feedback loop is real essense of agility.

October 12, 2008

Modules, Libraries, Components, Frameworks, Services and Platforms

Filed under: Computing — admin @ 9:21 pm

The software development is complex by nature and over the years, I have seen many abstractions for addressing this complexity such as modules, classes, libraries, components, packages, aspects, frameworks and platform, services, etc. Back when I started programming in 80s, I learned about Structured Programming and Top-down Design. Like modern good software practices it encouraged separation of concernsand was modular design. I learned from structured programming that modules should be loosely coupled and highly cohesive. I learned about various forms of coupling such as common, control, data, stamp, etc and how to avoid it. BASIC was my first programming language and I learned a number of languages afterwards, but C became my primary language. In that language, module meant c file that consisted of closely related functions.

I also understood concept of libraries (static), which were sort of modules or composition of modules that offered some useful functionality that I could link at compile/load time. In early 90s, I started learning object oriented programming and design and started using C++. It also highlighted modularity and introduced classes for combining data structure and behavior. It also emphasised encapsulation or information hiding and interfaces. Despite its impurity, I used C++ for many years. It was similar to C and it also used files for modules by defining closely related files in the same file.

In 1995, I also started using Java, which limited one class per file and offered packages for namespace. I heard many people equated modules to classes but I preferred packages for defining modules. Java also offered jar files for packaging libraries. In early days, Java also promoted JavaBeans as a way to add components and runtime wiring.

Around mid 90s to early 2000, I started learning about components, which were hot topics in those days. I learned Catalysis, Iconix and Component Software. A lot of companies were defining what components meant, such as SOM, Micrsoft’s COM, or their distributed counterparts such as DCOM, DSOM, CORBA, etc. Unlike static libraries, which were packaged as part of the application, those components offered binary and runtime pluggability. I used CORBA for many years, then moved to EJBs in early 2000s which offered more object oriened support for components. Historically, compile time components were difficult to use and led to DLL or Jar hell. Recent standars such as OSGI and Java JSR 291 offer nice dependency management and runtime isolation.

In mid 90s, I enrolled for Ph.D and was looking for interesting topics. One of my professor gave me some papers from Xeros Parc about aspect oriented programming. I ended up choosing different topic but liked the idea of aspects. AOP became popular in early 2000s and I have been using them whenever I get chance. Aspects addressed crosscutting concerns and offered a powerful way to modularize concerns like security, monitoring, transactions, caching, etc.

Web Services and Services oriented Architecture became popular in early 2000 and I started using Sun’s toolkit and Weblogic’s generators to convert Java/EJBs to Web Services. Similar to modules, libraries and components they try to sell on partitioning and reusability, though unlike former, the services didn’t have any compile or load time dependencies.

The component based software development then led to frameworks and I started hearing more about frameworks for UIs, eclipse IDE, etc. I found frameworks were different from libraries in several ways. For example, unlike libraries where client code simply invokes some functionality, the frameworks offered scaffolding to built applications and used inversion of control by offering hooks, callbacks or plugins to implment. I have been using a number of frameworks for many years such as Spring, Eclipse, Rails, etc.

For past a few years, more and more companies now offer platforms to build applications. The platforms are sort of like composition of frameworks with an API to build applications. Though, historically platforms were tied with specific operating systems or languages such as Java, .Net, iPhone, JavaME but Web has become the platform, which offers language and operating system independent services. There are unlimited choices for building new mashups and applications (see http://www.programmableweb.com/. Though, some of the web platforms such as Facebook, MySpace, Google App
Engine and Amazon Web Services offer more complete application hosting facilities and in the case of Facebook, MySpace or Twitter they also offer millions of potential users.

The cost of software development has become significantly cheaper due to open source and easily accessible libraries, frameworks and platforms. Though, what I described in this blog is no news to anyone, but I think it’s imporant to think about these differences and choices when building new applications.

October 3, 2008

Traits of good programmers

Filed under: Java — admin @ 11:00 pm

I love programming and have been doing it for more than 20 years. In that lifetime, I have also worked with a lot of good programmers and have discussed many times “what makes a good programmer” informally or during job interviews. Here are some of important traits that I have found in good programmers:

  • Simplicity and Clarity of thinking – I have found good programmers can think clearly and try to understand essense of underlying problem. Good programmers then develop simple solutions with minimal accidental complexity. I have found systems developed by good programs are easier to understand due to clarity of program design.
  • Passionate about programming – Programmming is a profession and I have seen a lot of programmers who considered programming a 9-5 job, who didn’t care about it outside the job. Many of those programmers did the same job for many years without learning anything new. I have found that best programmers care a great deal about programming and have a great passion about it. One way to distinguish programmers with passion is to ask them about side projects or open source projects that they started or worked on.
  • Continuous Learning – I have found good programmers spend a lot of time learning new skills or finding better ways to do things.
  • Generalist – Due to passion and ability to learn new things, good programmers have breadth of knowledge with varying skills and technolgies. They have modeling, UI, application, systems, database and other skills needed for softrware development.
  • Detail oriented – Programming requires a detail oriented person who can think about a problem and all issues that can effect the solution. I have found good programmers can think of all branch logic and all edge cases when solving a problem.
  • Visualize working of programs – Good programs have ability to visualize inner working of programs and can quickly pinpoint problem areas when things break.
  • Excellence vs Perfectionist – Real world projects are constrained by time and resources and good programmers opt for excellence by doing their best within those constraints rather than being perfectionist.
  • Inquisitive and inquiring mind – One of the hardest part of software development is determining key requirements and differentiating between wants and needs. Often stakeholders don’t know what they want. Good programmers work with users to detrmine what’s really needed for the system. Good programmers can probe users about real underlying problem that they are trying solve. In such systems, agile methodology also help where users can see something working and develop iteratively.
  • Communication – Good programmers communicate in multiple ways, they use design or code to communicate with other programmers. Senior programmers often need to sell or persuade other programmers about architecture or new practices.
  • Integrity and Courage – Though, this is a principle of XP but it’s also one of key trait of good programmers. I have found in most companies, management pulls deadlines and requirements out of the hat and good programmers have courage to speak up to the management when they see death march timelines.
  • Humility – This is also another attribute of XP but I have found in good programmers because programming is hard profession and everyone makes mistake. Though, I have also seen a lot of prima donnas who were smart (some of them) but were difficult to work with. On the other hand, I have found good programmers are humble and easy to work with.
  • Responsibility – Good programmers are profesional and they take full responsibility in developing fully tested and working solutions for the users.
  • Golden hammer – Due to being generalist, good programmers is less likely to use same solution or golden hammer to varying problems. Also, due to breadth of skills he/she is less likely to be swayed by technology or language de jure, instead good programmers try to evaluate real benefit of new technologies with some side projects.
  • Toolbox of solutions – Good programmers learn from varying solutions and often recognize patterns and similar problems that they have previously worked on. They use this toolbox of solutions and patterns when approaching new problem.
  • Productive – Often you hear about good programmers being 10 or 20 times more productive. Though, I admit it’s hard to measure productivity but I have found that good programmers are productive mostly due to above traits. For example, they develop simple code which is faster to develop and has less defect. They focus on essential probems that solve real problems. They are faster mostly because they practice alot with side projects and recognize patterns and previously solved solutions. When debugging and trouble shooting they can visualize software systems and can see problem areas. They don’t like to hackup things that will break in two weeks, instead they have courage to tell stakeholders risks of meeting unrealistic deadlines or releasing untested applications.

Powered by WordPress