[mod_python] Global, but threadsafe request object?

Graham Dumpleton grahamd at dscpl.com.au
Thu Sep 15 07:59:17 EDT 2005


On 15/09/2005, at 3:52 PM, Nicolas Lehuen wrote:

> The only way to do this safely and in a portable way would be to store 
> the request object in a thread-local variable (see 
> http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/302088 ). 
> Thread locals are only present in Python 2.4, though (but a pure 
> Python implementation is provided and nothing prevents it from running 
> on previous versions of Python).
>
>  Regards,
>  Nicolas
>
> 2005/9/14, Fabiano Sidler <fabianosidler at swissonline.ch>:
>>
>> In a web application I planning I need to access the request object 
>> from a big
>> number of functions and classes. Therefore I could pass it each time 
>> to each
>> of the objects working on it, which has very ugly disadvantages like 
>> inherent
>> portability loss and weird parameter lists. So my question to you: Is 
>> there a
>> way to make it global-like, if necessary over a singleton-like 
>> wrapper class
>> returning it? I know, this looks more likely a python problem than a 
>> modpython
>> one, but perhaps someone here knows a simple solution with using mod-
>> python specific code?

In the absence of Python 2.4, I use the code given at end of email. The
_cache_request() method should be called at the start of the top level
handler. Rather than do this in every handler, you could probably also
create a special handler which does only that and then returns
apache.OK. You can then use fact that you can list multiple handlers to
PythonHandler directive. For example:

   PythonHandler my_request_object_cache
   PythonHandler mod_python.publisher

# my_request_object_cache.py

try:
     import threading
     _current_thread = threading.currentThread
except:
     def _current_thread():
         return None

_cache = {}

def _discard_request(thread):
     try:
         _cache[thread].pop()
         if len(_cache[thread]) == 0:
             del _cache[thread]
     except:
         pass

def _cache_request(req):
     thread = _current_thread()
     if _cache.has_key(thread):
         if _cache[thread][-1] == req:
             return
         _cache[thread].append(req)
     else:
         _cache[thread] = [req]

     req.register_cleanup(_discard_request,(thread,))

def current_request():
     try:
         thread = _current_thread()
         return _cache[thread][-1]
     except:
         pass

# Untested handler which will cache request when chain
# of handlers is defined. Make this the first handler
# defined to PythonHandler directive.

def handler(req):
     _cache_request(req)
     return apache.OK



More information about the Mod_python mailing list