[Web-SIG] Alternative to threading.local, based on the stack

Matt Goodall matt at pollenation.net
Fri Jul 4 14:39:25 CEST 2008


Iwan Vosloo wrote:
> Hi,
> 
> Many web frameworks and ORM tools have the need to propagate data
> depending on some or other context within which a request is dealt with.
> Passing it all via parameters to every nook of your code is cumbersome.
> 
> A lot of the frameworks use a thread local context to solve this
> problem. I'm assuming these are based on threading.local.  
> 
> (See, for example:
> http://www.sqlalchemy.org/docs/05/session.html#unitofwork_contextual )
> 
> Such usage assumes that one request is served per thread.
> 
> This is not necessarily the case.  (Twisted would perhaps be an example,
> but I have not checked how the twisted people deal with the issue.)

You're correct that Twisted Web does not allocate a thread per request.
All requests are handled by an event loop in the main thread.

However, the WSGI request handled in Twisted does actually spawn a
thread to run the WSGI application because most WSGI applications are
blocking.

> 
> The bottom line for me is that if you build a WSGI app, you'd not want
> to restrict it to being able to run in a one request-per-thread setup.
> 
> So I've been playing with the idea to use something that creates a
> context local to the current call stack instead. I.e. a context (dict)
> which is inserted into the call stack at some point, and can be accessed
> by any method/function deeper in the stack.

In Twisted, the call stack tends to gets fragmented during a sequence of
asynchronous calls because of its callback mechanism. Basically, you're
hopping in and out of the Twisted reactor (the event mainloop) all the
time. Leaving something in the call stack would not work at all.

The ideal solution is, of course, to pass everything around to whatever
needs it. However, there's really tedious at times.

Whatever the architecture of the web server there is always a request
or, in case of WSGI, an env dict. Therefore, request-scope objects
should be associated with the request.

> 
> The normal use case for this is to propagate a database connection. But
> it can also be used to propagate other things, such as information about
> the user who is currently logged in, etc.
> 
> Since this is one way of creating objects that are global to a context
> (the call stack), I'm sure it is in some ways evil and can be abused.
> But that criticism can be levelled against the thread-local solution
> too...

Yep, thread and call stack locals are both bad. Think in terms of
request locals instead and things start getting better.

> 
> I attach some code to illustrate - and would appreciate some feedback on
> the idea and its implementation.
> 
> -i
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Web-SIG mailing list
> Web-SIG at python.org
> Web SIG: http://www.python.org/sigs/web-sig
> Unsubscribe: http://mail.python.org/mailman/options/web-sig/matt%40pollenation.net


-- 
Matt Goodall
Technical Director, Pollenation Internet Ltd

Registered Number: 4382123
Registered Office: 237 Lidgett Lane, Leeds, West Yorkshire, LS17 6QR
A member of the Brunswick MCL Group of Companies

w: http://www.pollenation.net/
e: matt at pollenation.net
t: +44 (0) 113 2252500

This message may be confidential and the views expressed may not reflect
the views of my employers. Please read http://eudaimon-group.com/email
if you are uncertain what this means.


More information about the Web-SIG mailing list