[mod_python] mod_python sessions, locking, and PSP

Graham Dumpleton grahamd at dscpl.com.au
Sun Aug 13 18:49:59 EDT 2006


Jim Gallacher wrote ..
> Michael Spang wrote:
> > I recently ran into deadlocks using sessions in both my mod_python
> > handler and in psp. I've read through the thread at
> > http://www.modpython.org/pipermail/mod_python/2005-May/018035.html and
> > understand that this occurs because both my handler and PSP create their
> > own session instance and attempt to lock the session.
> > 
> > My question is: why doesn't the mod_python sessions module keep a
> > reference to each constructed session object and the thread that has
> it
> > locked? 
> 
> Easier said than done in mpm-prefork or mpm-worker. It's possible to
> keep track of the session object within a single request, but difficult
> (as in nearly impossible) to do it across requests in these 2 mpms.

Hmmm, what do you mean by across requests here? The only thing I can think of
that even makes sense doesn't even relate to which MPM is used. This is the
problem in 3.2 whereby if an internal redirect occurs and the parent handler
had acquired the session and not unlocked it, that an attempt by the handler
for the sub request to also acquire the session object will result in a
deadlock.

I have demonstrated code before which can be used to make this work provided
that both parent and sub request are in the same interpreter. In short it would
stash the session object in a global area where the thread was the key. It
would be up to any handler to first check in the cache for the session object
before deciding to create its own and in turn store that in the cache. The
request handler would also need to register a cleanup handler to ensure that
any reference was removed at the end of the request. This could be done as part
of the implementation of the cache though.

Now, having said that, in mod_python 3.3 there is a change that may make all
this simpler to do and which may also allow sharing of the session object
between handlers executed within the context of different interpreters. The
change is that req.main now provides access to the actual request object of
a parent request whereas previously the Python part of the object was a new
wrapper around the request_rec structure for the parent request.

What this means is that the following may actually work in a handler of a
sub request.

  def handler(req):
    if req.main and hasattr(req.main, 'session'):
      req.session = req.main.session
    else:
      req.session = Session(req)
      if req.main:
        req.main.session = req.session

I can't remember how thoroughly I tested this and whether it does work
across interpreters. It should for simple data and whether a session object
is too complicated I don't know.

Graham




More information about the Mod_python mailing list