[Web-SIG] Asynchronous streaming in WSGI
Phillip J. Eby
pje at telecommunity.com
Thu Aug 5 18:19:50 CEST 2004
I've been looking at a possible change to the WSGI protocol to address some
issues raised by Grisha and Ian. But I'm not sure that the change is best,
given the range of existing platforms and applications that may *currently*
use asynchronous streaming of responses, even though in many ways the
change would handle asynchronous streaming *better*.
Let me explain. The previous WSGI proposal was based on an interface like:
def runCGI(inp,out,err,env):
# do everything
The modified interface, that I've been playing with in peak.web is:
def handle_http(env):
return status_string,header_list,output_iterable
The ideas that changed here are:
* Separate status from headers and output
* Don't require servers to parse headers or create an output buffer
* Allow lengthy output to be streamed *after* the function returns, to
avoid tying up a task thread in multi-threaded servers
* Allow non-CGI variables (e.g. 'wsgi.input_stream', 'wsgi.error_stream',
'wsgi.version', 'wsgi.multi_threaded', etc.) in the environment to avoid a
separate configuration method and simplify chaining of processors
As a result of these changes, it should also be much easier to write
request preprocessors, response postprocessors, and other kinds of
intermediaries between the web server and the actual
application/frameworks, because less parsing and buffering are
required. Last, but not least, an interface like this should be easier to
implement in asynchronous web servers, because they can just invoke
'iterator.next()' when they need another block to send out.
I think these are improvements in the direction that folks requested,
*except* for one issue: unbuffered streaming output in existing code can't
use this. A prime example is Zope, whose response.write() method does
streaming output. Under the revised WSGI, there's nothing to write *to*,
so such existing code would have to run in a separate thread from the web
server and communicate via a queue. This doesn't seem like a great idea.
So, there are several possible ways to deal with this:
1) Stick with the old interface
2) Go with the newer interface, and try to lobby frameworks that support
this type of "push" to make changes to support it
3) Publish both interfaces, and push for a stdlib module that can convert
between them
4) Some other idea I haven't thought of :)
Opinions? Questions? Ideas?
More information about the Web-SIG
mailing list