Ben Bangert wrote:
>>And I can see the point for turbogears.request.wsgi [1] or such so
>>you don't have to pass the environment around everywhere.  The point
>>of middleware is to be framework-neutral, not to force everything
>>through the environment.
> 
> 
> Yup, though if TG is increasing Paste-compatibility at the same time,
> some Paste middleware perhaps similar to the paste.deploy.config
> middleware could be used to 'register' such thread-locals (mainly
> because it can be tricky to clean-up at the end of a wsgi app request).

I wasn't tracking this discussion as it happened, but threadlocal stuff 
came up a lot here.  After some discussion with Ben on IRC, I'm thinking 
that one thread-local WSGI environment can satisfy nearly every use 
case, in a fairly nice way.

So lets say that foo.wsgi_environ is a threadlocal variable that points 
to the current WSGI environment for this request.  It is set up with 
WSGI middleware, and stacked for the case of multiple stacked requests 
(like when doing an internal redirect).  Basically, we make sure it is 
accurate, and if there's no current request it bails out with an 
exception.  (cherrypy.request actually sticks around after the request, 
but rhubarbtart.request doesn't -- RT's CP compatibility copies CP's 
behavior, though)

Anyway, given that -- in one, well-known and importable location (and 
yes, with all the problems that implies) -- you can build up all sorts 
of other objects in a way that feels fairly safe to me.

For instance:

import foo
class Request(object):
     def __init__(self, wsgi_environ=foo.wsgi_environ):
         self.environ = wsgi_environ
     @property
     def params(self):
         if 'myframework.request.params' not in self.environ:
             self.environ['myframework.request.params'] = 
parse_params(self.environ)
         return self.environ['myframework.request.params']
     ... and other methods ...

request = Request()


The idea being that *no* state is kept in these objects -- they put all 
state into the environment.  Each object is a kind of proxy around the 
request object.  The proxy can be thicker (like in this example), or 
pretty thin (e.g., put the actual object in the environment, and then 
create an object that proxies all method access).

Though there is one import problem -- where to keep this threadlocal 
wsgi_environ -- all the other import problems aren't an issue.  If 
objects are careful about checking state in the environment, they can 
see changes that come about from other frameworks.  (In this example I 
am *not* being careful, but in paste.request.parse_formvars() I am more 
careful)

There's still some open issues in my mind.  For example, I think these 
kinds of objects should probably have a .copy() method or something that 
gets a concrete dictionary instead of the threadlocal, so that you can 
get a version of the object that won't disappear under your feet (once 
the request has finished).  But the basic pattern feels good to me. 
Except for the import problem :-/ -- though a clever middleware could 
probably set multiple threadlocal's to match the environment, with the 
only interaction through a key in the environment itself.

-- 
Ian Bicking  /  [EMAIL PROTECTED]  /  http://blog.ianbicking.org

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"TurboGears" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/turbogears
-~----------~----~----~----~------~----~------~--~---

Reply via email to