[Web-SIG] WSGI uses
tony at lownds.com
tony at lownds.com
Thu Aug 19 21:37:01 CEST 2004
> For instance, I was thinking about setting up something for Medusa with
> WSGI. But though I think asynchronous code seems like a good server
> architecture, I'm not that interested in it for applications. But this
> iteration of the WSGI spec allows for async pretty well; you can tell
> you are in that situation when wsgi.multiprocess is false and
> wsgi.multithread is false, and the iterator output can produce the data
> fairly well.
>
How do you decide when to actually send the data back to the client? On
every yield?
That could perform badly if one does
def application(...):
...
return open(filename)
...that usage is actually suggested in the spec.
In a similar vein, if servers/gateways send data back on every call to
write, and applications don't take that into account, they could also
suffer in performance. It seems like an object with write() and flush()
makes it easier to provide guarantees about streaming -- which I think
WSGI ought to do.
> I then realized that threading itself could be a piece of middleware --
> you just have to do the proper buffering with input and output. An
> intelligent application that realizes it can't run as an async process
> could install this middleware itself when necessary.
>
Did you find that an async server has to provide a new buffer for every
request to implement the write() function correctly?
Although I suggested the (env, start_response) -> write() protocol, it
just can't adapt to future needs. As soon as more than one function/method
is needed, the API is broken -- and can't be fixed.
For instance, having one method to start the response and NOT get a
write() function could allow server/gateways avoid some work...
What about passing in a class with class methods in place of the
start_response method? i.e.
class ContextLogic:
@classmethod
def start_writing(cls, env, status, headers):
cls.start(env, status, headers)
# prepare output object
return output.write
@classmethod
def start(cls, env, status, headers):
....
@classmethod
def request_url(cls, env):
...
@classmethod
def get_input_stream(cls, env):
...
Contexts can be re-used, and middleware does not have to delegate (it just
subclasses on the fly).
class Pooler:
class PoolingLogicMixin:
@classmethod
def get_pool(cls, env):
...
def __init__(self, subapp, ...):
self.subapp = subapp
def __call__(self, context, env):
class NewContext(PoolingLogicMixin, context): pass
return self.subapp(NewContext, env)
One more thought: how about using the term WSGI "driver" instead of
server/gateway?
-Tony
More information about the Web-SIG
mailing list