[mod_python] Threading and apache.import_module

michael bayer mike_mp at zzzcomputing.com
Sat Jun 18 15:29:46 EDT 2005


I use the "two-check" approach to this, which allows multiple threads  
to get at an already-imported resource without blocking each other,  
while allowing the actual import to occur in a threadsafe  
manner...suppose every access of a module calls "verify_module" which  
reloads the module if needed, using the functions _needs_reload to  
perform a check and _reload_module to do the actual reload:

    import threading
    mutex = threading.RLock()

    def verify_module(module):
        if _needs_reload(module):
           mutex.acquire()
           try:
               if _needs_reload(module):
                    _reload_module(module)
           finally:
               mutex.release()

in the normal case, threads will call _needs_reload() without  
synchronization and return, without any bottleneck occuring.  when  
the reload is actually required, threads will line up onto the  
mutex.acquire() and re-check once entering the critical section, thus  
allowing only the first thread inside to actually perform the reload.

an additional optimization is to use a unique mutex for each  
module...that way multiple threads that are reloading several  
different modules also don't block each other.

the issue of other threads executing code against the module while  
its being reloaded is not really addressed here.  as a normal reload 
() or imp.load_module() doesnt remove any of the old module values,  
its usually (but not always) the case that nothing really  
happens....unless there are persistent pointers to the module's  
globals lying around elsewhere, which then become outdated.    I did  
see a reload() implementation that loads a new module under a  
temporary name, then moved it's dictionary over, which attempts to be  
more atomic...I havent tried it but its over at http:// 
lists.canonical.org/pipermail/kragen-hacks/2002-January/000302.html .

On Jun 17, 2005, at 3:09 PM, Dan Eloff wrote:

> Well this is the biggest problem in my otherwise threadsafe code. From
> what I've read, importing/reloading modules in a threaded environment
> is just plain dangerous. There could be any number of requests
> executing code from and accessing global variables in a module when it
> changes and gets reloaded. Then you have the two level problem of what
> happens to the executing requests, as well as what happens when
> multiple incoming requests all spot that the module has changed, and
> reload it multiple times in quick succession, re-executing code in the
> module scope (this is pretty much worst case)
>
> I know Graham knows a lot more about this than I do (help!).
>
> I do have a lot of flexibility here, since I'm using my own publisher
> I do not have to use apache.import_module. In fact I would prefer to
> not have the whole importing/reloading business affect my code outside
> of the publisher, that way I can change things internally at will.
> Clearly one option is to create a simple import function that imports
> once only in a production environment, and every time in a development
> env, but I'm still interested in exploring the options.
>
> -Dan
>
> _______________________________________________
> Mod_python mailing list
> Mod_python at modpython.org
> http://mailman.modpython.org/mailman/listinfo/mod_python
>


More information about the Mod_python mailing list