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
-~----------~----~----~----~------~----~------~--~---