Thursday, March 5, 2009

The Cherrypy Web Site Process Bus

The Cherrypy web application framework defines several process utilities for communication across several website components. One such utility is the Web Site Process Bus. This bus is implemented as a class called Bus. The bus implements a micro publish subscribe event system along with some default subscribers to carry-out the default server behaviour. An interesting note about this publish-subscribe framework; every subscriber is guaranteed to execute, even if previous subscribers raise an exception.

The Bus class defines several methods that will publish basic server state change events such as starting and stopping. Here is an illustration of what the Bus class looks like.

Here, we can see that the Bus class depends on the _StateEnum enumeration. This enumeration holds all possible states a Cherrypy server may be in at any given time.

The subscribe() method will subscribe the specified callback to the specified channel. There is also an optional priority parameter that may be set.

The unsubscribe() method will unsubscribe the specified callback from the specified channel.

The publish() method
will publish the specified parameters to the specified channel.

The _clean_exit() method will check if the bus is in an EXITING state before exiting the bus.

The start() method will publish an event on the start channel and put the bus in a STARTING and START state.

The exit() method will publish an event on the exit channel and put the bus in a EXITING state.

The restart() method will set the execv attribute to True and invoke the exit() method.

The graceful() method will publish an event on the graceful channel.

The block() method will block execution in the current thread of control until the bus is in the EXITING state. Once reached, all threads are then joined so the current thread will wait until they have terminated. Finally, if the execv attribute is set to True, _do_execv() is invoked.

The wait() method will block execution until the bus is in the specified state.

The _do_execv() method will attempt to restart the process in which cherrypy is running.

The stop() method will publish an event on the stop channel and put the bus in a STOPPING and STOPPED state.

The start_with_callback() method will start a new thread for the specified callback and then invoke the start() method.

I think having a platform independent bus like this in place is a very smart design decision. It is very useful and helpful for web applications to be able to reason about the state of the process in which it is running. This is especially true in today's distributed environments.