Session Locking and Performance in CherryPy

While working on that firewall project I keep alluding to, I came across an interesting caveat when using sessions (tools.sessions) and static file directories (tools.staticdir):

Sessions are locked on a per-request basis meaning while a request is being processed, all other requests by that session will block until the lock is released (by default at the end of the response handler).

This is a Very Good Thing, at least as the default behavior. Its the only safe way to automatically handle sessions.

However, this can become a performance problem, especially for those of us addicted to tabbed browsing. Take this trivial app as an example:

#!/usr/bin/python
import cherrypy, time
 
class Test:
    @cherrypy.expose
    def page1(self):
        # Simulate long operation
        time.sleep(20)
        return "*Yawn*"
 
    @cherrypy.expose
    def page2(self):
        return "Hello World!"
 
cherrypy.config.update({
    'tools.sessions.on': True, 
    'tools.sessions.storage_type': 'ram'})
cherrypy.quickstart(Test(), '/')

Start it up, and then go to these pages in order in 2 different tabs:

  1. http://localhost:8080/page1
  2. http://localhost:8080/page2

You’ll notice that page2 doesn’t load until page1 is finished loading! This effectively limits sessions to 1 request at a time. For many web sites this might not be an issue. However, for complex web applications which might be doing time consuming operations on the server, this could give users the impression the server has crashed.

Fortunately this is a very easy issue to resolve. The best way is to do explicit session locking manually.

However, if implicit session locking works for you most of the time you can sneak in a cherrypy.session.release_lock() into your code Like this:

#...snip...
    @cherrypy.expose
    def page1(self):
        # Do any session manipulation here!
        cherrypy.session.release_lock()
        # Simulate long operation
        time.sleep(20)
        return "*Yawn*"
#...snip...

Now hit page1 and 2 again and notice that page2 loads immediately!

At Kevin’s suggestion I turned off the visual editor in WordPress. I had thought of this before, but couldn’t find where the option to disable it was! Evidently its a per-user setting which makes sense.

At any rate, WordPress seems to be leaving my whitespace alone now! Thanks Kevin!

2 Responses to “Session Locking and Performance in CherryPy”

  1. Christian Wyglendowski Says:

    I can see how using implicit session locking and just calling release_lock() when you need it can be nice. Great overview of your problem and how it was solved.

  2. Timothy Kendall Says:

    I’m a newcomer to cherrypy and am operating under a bit of time pressure. I can’t even get as far as trying what you suggest here, because I cannot get sessions to work at all.

    I’ve set the config “tools.sessions.on = True”, and have already discovered that while cherrypy.quickstart() takes the config-file name as an argument, it doesn’t do anything detectable with it. Only when I do the config update myself does the config file “take”.

    But the cherrypy object still does not have a “session” attribute, so any and all attempts to do anything with “cherrypy.session” cause an exception. I take it that there’s some bit of initialization magic that I haven’t found in the (very sketchy) online documentation I’ve been able to find, or in the (equally sketchy) book.

    The documentation says that once that config parameter is set, sessions “work”. But they don’t seem to be present at all, much less work.

    I’m using cherrypy 3.0.2.

    Any hint, or pointer to some real documentation, would be greatly appreciated.

    Many thanks.

Leave a Reply