[mod_python] global var on 2.7

Graham Dumpleton grahamd at dscpl.com.au
Sun Jul 10 18:16:03 EDT 2005


>> I'd do this, probably:
>>
>> # CacheBigdic.py
>>
>> bigdic = looong_and_painful_process()
>>
>> # publishedmodulewithuniquename.py
>>
>> import CacheBigdic
>> def index(req):
>>     ...
>>     use(CacheBigdic.bigdic)
>>     ...

This way of doing things can be problematic and may not be advisable.

The problem is that since the long and painful process is done at time
of import (while the thread holds the global import lock) in a threaded
MPM, you will block every request in the process which might want to
import a module. Thus, if it took ten seconds, in the worse case when
Apache process is just started, all requests could be stalled for ten
seconds.

You are much better off doing it the first time you need it as you
were doing. Doing it only the first time it is required also enables
you to more easily return an error response if it fails. Subsequent
requests which try again automatically to initiate the action.

If you do create it the first time it is required like this though,
in a multithreaded MPM, you will need to use a thread lock to prevent
more than one thread trying to create it the first time at the same
time.

>> If you find errors appearing in your apache log under heavy load, you
>> may need to alter CacheBigdic.py:
>>
>> try:
>>     bigdic = looong_and_painful_process()
>> except TheErrorYouSee:
>>     bigdic = looong_and_painful_process()
>>
>> It looks redundant, but it's needed because the module is cached. In 
>> any
>> case, it's important to protect yourself if your bigdic gets you in 
>> trouble.

And if it fails the second time as well? At some point you would have
to give up and the only way to reinitiate the action is to reload the
module with no means of returning an customised error response as to
what went wrong. Thus doing it at the time of the request is again
preferable to do it at the time of import.

Graham



More information about the Mod_python mailing list