Stateless Objects
published: Tue, 4-Jan-2005 | updated: Thu, 27-Oct-2005
The term "stateless object" came up in a conversation today, and although the term was familiar -- I'd definitely heard it before in relation to web applications -- I was not sure what exactly it meant.
So, some research later, here's my take. And I say "my take" because there is some ambiguity about it, with Microsoft Transaction Server (MTS) muscling in with its definition.
In a web application there are several physical layers or tiers. At a minimum there are three layers: the first is the database server that maintains the data persistence in the system; the second is the web server that accepts HTML requests and builds responses in the form of web pages; the final one is the client's browser.
Now in some cases the database server and the web server may be on the same machine, but in general they are not. The reason for this is scalability. The easiest way to scale a web application is to add extra web servers and have a load balancer to direct requests to the web servers so that the overall load is spread among them. Using this structure, you can add new servers or remove others at will.
Now, of course, all this doesn't come for free: you have to develop your web application to be aware that it may be run on multiple web servers.
The issue to understand here is that the client browser may be talking to different servers with different requests at different times, yet it must appear as if the objects it's manipulating are there on every server.
(For the purposes of discussion, let's assume that the web application is a simple e-commerce site with a shopping cart, and that the shopping cart is expressed as a collection of objects in the application on the web server. Obviously the collection of objects has some persistent representation in the database.)
Suppose the user adds a set of items to his shopping cart. As he fills his cart, his client browser may communicate with more than one web server. Since the web servers do not communicate between themselves (they merely run the same web application and talk to the one and only database server) the shopping cart has to give the appearance of being "passed around" between the servers, or if you like, the client can make the assumption that it is talking to only one server.
So what happens to the shopping cart objects during this series of interactions? They have to be persisted in some way. There are several alternatives: pass the data for the cart to the client browser (in viewstate, for example); persist the cart in the database; use some other equivalent method.
But whatever you do, you essentially have to save the cart object somehow, get it out of the server's memory. You cannot leave the cart in Session, for example, because the next request from the client may go to another web server altogether and the Session variables on that server will be different than on the previous one. In fact, every interaction (or transaction) between the client and the web application may turn out to be via a different web server.
This is where stateless objects come in. State, in this scenario, is the object's data values, at least those values that are different from those in a new object. Whenever you need to use a stateless object, you have to create it, read the object's state from some persistent store, and then the "stateful" object is ready to use. Once you've finished using the object for that particular transaction, you have to persist the object's new state, and then destroy the object. The stateful object (that is, containing data values that haven't yet been persisted) cannot survive across request-response interactions.
Of course, depending on the semantics of the application, you will probably not "create" or "destroy" the stateless object; you'll instead use object pooling via a factory method or class. That is, when you need a stateless object, you'll call some method on a class that internally maintains a set of such objects. If there is a spare object of the correct type in the pool it is returned, otherwise a new object is created and returned (after which its state is read from persistent storage). Once you've finished with the object, and its state has been persisted, you'll call another method on the same class that will add the now unused object back to the pool. (Notice that there can be a separate pool of these objects for each web server: they're essentially anonymous object clones without their state.)
In essence a stateless object is just a collection of methods. One of these methods is to read its state from storage, and another is to save the complete state back to storage. The rest of the methods and properties are only meaningful once the object is stateful.
Oh, and the mention of "transactions" should have alerted you to the use of MTS to maintain the stateless objects. But that is a discussion for another day.