Ñò
ô†³Kc @ sÆ d Z d d k Z d d k i i Z d d d d g Z d e f d „ ƒ YZ d e f d „ ƒ YZ d
e f d „ ƒ YZ d e f d „ ƒ YZ
d e f d
„ ƒ YZ e ƒ Z d „ Z
e
i e
_ d S( s©
Registry for handling request-local module globals sanely
Dealing with module globals in a thread-safe way is good if your
application is the sole responder in a thread, however that approach fails
to properly account for various scenarios that occur with WSGI applications
and middleware.
What is actually needed in the case where a module global is desired that
is always set properly depending on the current request, is a stacked
thread-local object. Such an object is popped or pushed during the request
cycle so that it properly represents the object that should be active for
the current request.
To make it easy to deal with such variables, this module provides a special
StackedObjectProxy class which you can instantiate and attach to your
module where you'd like others to access it. The object you'd like this to
actually "be" during the request is then registered with the
RegistryManager middleware, which ensures that for the scope of the current
WSGI application everything will work properly.
Example:
.. code-block:: python
#yourpackage/__init__.py
from paste.registry import RegistryManager, StackedObjectProxy
myglobal = StackedObjectProxy()
#wsgi app stack
app = RegistryManager(yourapp)
#inside your wsgi app
class yourapp(object):
def __call__(self, environ, start_response):
obj = someobject # The request-local object you want to access
# via yourpackage.myglobal
if environ.has_key('paste.registry'):
environ['paste.registry'].register(myglobal, obj)
You will then be able to import yourpackage anywhere in your WSGI app or in
the calling stack below it and be assured that it is using the object you
registered with Registry.
RegistryManager can be in the WSGI stack multiple times, each time it
appears it registers a new request context.
Performance
===========
The overhead of the proxy object is very minimal, however if you are using
proxy objects extensively (Thousands of accesses per request or more), there
are some ways to avoid them. A proxy object runs approximately 3-20x slower
than direct access to the object, this is rarely your performance bottleneck
when developing web applications.
Should you be developing a system which may be accessing the proxy object
thousands of times per request, the performance of the proxy will start to
become more noticeable. In that circumstance, the problem can be avoided by
getting at the actual object via the proxy with the ``_current_obj`` function:
.. code-block:: python
#sessions.py
Session = StackedObjectProxy()
# ... initialization code, etc.
# somemodule.py
import sessions
def somefunc():
session = sessions.Session._current_obj()
# ... tons of session access
This way the proxy is used only once to retrieve the object for the current
context and the overhead is minimized while still making it easy to access
the underlying object. The ``_current_obj`` function is preceded by an
underscore to more likely avoid clashing with the contained object's
attributes.
**NOTE:** This is *highly* unlikely to be an issue in the vast majority of
cases, and requires incredibly large amounts of proxy object access before
one should consider the proxy object to be causing slow-downs. This section
is provided solely in the extremely rare case that it is an issue so that a
quick way to work around it is documented.
iÿÿÿÿNt StackedObjectProxyt RegistryManagert StackedObjectRestorert restorert NoDefaultc B s e Z RS( ( t __name__t
__module__( ( ( s2 /usr/lib/python2.6/site-packages/paste/registry.pyR b s c B s e Z d Z e d d „ Z d „ Z d „ Z d „ Z d „ Z d „ Z d „ Z
d „ Z d
„ Z d „ Z
d „ Z d
„ Z d „ Z d „ Z d „ Z d „ Z d d „ Z d „ Z d „ Z d e i e _ d „ Z d e i e _ d d „ Z d e i e _ RS( sÈ Track an object instance internally using a stack
The StackedObjectProxy proxies access to an object internally using a
stacked thread-local. This makes it safe for complex WSGI environments
where access to the object may be desired in multiple places without
having to pass the actual object around.
New objects are added to the top of the stack with _push_object while
objects can be removed with _pop_object.
t Defaultc C sB | | i d