[Twisted-Python] wsgi thread synchronization
I'm crossposting because although my use case is in web, this is more of a question about dealing with threads in twisted. I have a decent academic understanding of threads, but I've never really used them in Python or Twisted. I've just moved from a mod_python WSGI container running on prefork apache2 to a container running on twisted.web, and I realized that I now have threading considerations I didn't before. Since my potential synchronization problems are actually quite few, I've been getting by just by using threading.BoundedSemaphore to manage a couple of thread-sensitive areas of the web app. However, I already have a dependency on Twisted core, so it occurs to me that there are probably nicer, twistier ways of doing this. For example, I have a section of code like: host_tree = {} host_tree_lock = threading.BoundedSemaphore def get_application(env): global host_tree, host_tree_lock host = env.get('HTTP_HOST', env['SERVER_NAME']) host_tree_lock.acquire() if not(host in host_tree): _load_plugins(env) host_node = host_tree[host] if not(host_node.has_path(env['REQUEST_URI'])): _load_plugins(env) app = host_node.get_data_at(env['REQUEST_URI']) host_tree_lock.release() return app The only variable shared between threads is the `host_tree` global (the `env` variable is the WSGI environment, which is unique per thread, and the resulting `app` object is immutable). This works for me and is sufficient for my needs, but I'd appreciate a sanity check from anyone with some thread karma to spare. Thanks again, -phil
On 7/27/07, Phil Christensen <phil@bubblehouse.org> wrote:
host_tree = {} host_tree_lock = threading.BoundedSemaphore
def get_application(env): global host_tree, host_tree_lock
host = env.get('HTTP_HOST', env['SERVER_NAME'])
host_tree_lock.acquire()
[bunch of stuff]
host_tree_lock.release()
return app
The only variable shared between threads is the `host_tree` global (the `env` variable is the WSGI environment, which is unique per thread, and the resulting `app` object is immutable). This works for me and is sufficient for my needs, but I'd appreciate a sanity check from anyone with some thread karma to spare.
The most immediately obvious problem is that you're not protecting yourself from an error in the code between the acquire and the release. You'll want to start a try: block immediately after the acquire and move the release into a finally: block. -- Christopher Armstrong International Man of Twistery http://radix.twistedmatrix.com/ http://twistedmatrix.com/ http://canonical.com/
participants (2)
-
Christopher Armstrong
-
Phil Christensen