subbu.org

More Reasons to Avoid State

with 4 comments

Whenever the topic of statefulness vs statelessness comes up, most people list performance and scalability as two main reasons to avoid state. Sometimes, these debates get very passionate with some people arguing that state is not all that bad. There are some valid points in both sides of the argument. It is true to that maintaining state can impair performance and scalability, and applications need to take extra care to keep some decent levels performance and scalability. But I think we don’t often discuss how state affects architecture and deployment of applications, and these issues have some really long-term consequences.

Think of a few scenarios:

  1. Joe Developer built a nice shopping cart app for an ecommerce site. This app manages the shopping cart in the user’s session, and cleans it up after checkout. The app is up and running. Joe now wants to make some fixes/enhancements to the app and wants to push the new version to the production server.
  2. The shopping cart app has a small configuration file to configure the app (conveniently stored in the WEB-INF/lib directory). Joe loads this file at deployment time, and keeps the data in memory. Joe now fiunds that he needs to modify that file to adjust the behavior of the shopping cart.

Fair enough? Let’s take any popular J2EE server (including Tomcat) out there. Joe can simply undeploy the existing app, make changes, and redeploy the app - all without having to restart the server. All J2EE servers have decent GUI or scriptable tools to do this.

But this is not an acceptable solution. By undeploying and redeploying the app, users will lose their existing sessions, and therefore will have to start all over. So, Joe will have to make the changes when no users are interacting with the site. If the site is popular, it is very difficult to find such time. There are a few solutions to work around this. Joe can maintain two clusters running the same app, and when it is time to make changes, Joe can direct the traffic for new users to one of the clusters, wait for timeout of the sessions on the other cluster, and then take down the second cluster. He can then make changes to the app on the second cluster, bring it up, and then repeat the process all over with the other cluster. This approach can work, but is painful to adopt.

What is wrong here?

First of all, J2EE application servers are architected such that applications can maintain state. Applications are not forced to maintain state, but when an application decides to maintain state, it can take advantage of the server’s runtime for things like replication and failover. But the plumbing used for replication and failover comes at an expense - both in terms of extra CPU cycles and network bandwidth, and deployment complexity.

Secondly, J2EE application servers have a costly process for deploying applications. Why not just point the server to application components on the file system and let the server run those components when required? Instead, what we have is a complex set of deployment descriptors, and a costly process of initializing application components (servlets, EJBs etc.) and that leads to the next problem.

I find it very common to find applications loading data from configuration files at deployment time, and use that later (I too have sinned). Some applications also include some one-time processing of that configuration data at deployment time. In fact, the servlet API has some interfaces for doing things at deployment and undeployment. This makes sense when you think of request-time performance, but not when you include production-time deployment and changes.

In Joe’s case, since the shopping cart app loads the configuration data at deployment time, after making changes to the configuration file, he needs to redeploy the app. So making changes is an expensive proposition.

Here is the dream scenario:

Joe makes changes to the app on the production server (of course, via some scripts, and after validating the changes on a staging server). No users are disturbed. There is no complex process for shutting down the app and bringing it up again. Changes become effective for future requests.

We really need to think hard about these problems from ground-up before choosing to keep state.

  • Digg
  • del.icio.us
  • Google

December 27th, 2004 at 12:11 pm

RSS feed

4 Comments »

Comment by John D. Mitchell at 2004-12-27 12:40:36

“State is the second worst thing in distributed computing.
 No state is the worst.” –John Ousterhout

 
Comment by Behrang Saeedzadeh at 2004-12-27 13:39:17

You’re mixing things up: statelesness/statefulness does not have anything to do with J2EE deplyment descriptors. Deployment descriptors are necessary, whether you want to maintain state in your application or not.

And the problem with shopping cart config file can be solved without losing state. One way can be to check the modification date of the config file periodically. And this also is not only a problem that stateful applications: A stateless application may also load some configuration parameters from config files at deployment time.

By the way, you’re talking about session state, aren’t you?

And I’m not sure if it’s good to avoid state or not, but whatever, happy new year ;-)

 
Comment by No one at 2004-12-27 13:54:53

Try to build any application without state. It’s impossible.

 
Comment by Subbu Allamaraju at 2004-12-27 16:21:29

Regarding the comment “You’re mixing things up: statelesness/statefulness does not have anything J2EE deplyment descriptors…”

True. The issue is not about deployment descriptors, but the way most of these servers maintain their own state. The result is rigidity.

 
Name (required)
E-mail (required - never shown publicly)
URI
Your Comment (smaller size | larger size)
You may use <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> in your comment.

Trackback responses to this post