[Web-SIG] PEP 444 / WSGI 2 Async

P.J. Eby pje at telecommunity.com
Fri Jan 7 17:10:43 CET 2011


At 12:39 AM 1/7/2011 -0800, Alice Bevan­McGregor wrote:
>Earlier in this post I illustrated a few that directly apply to a 
>commercial application I am currently writing.  I'll elaborate:
>
>:: Image scaling would benefit from multi-processing (spreading the 
>load across cores). Also, only one sacle is immediately required 
>before returning the post-upload page: the thumbnail.  The other 
>scales can be executed without halting the WSGI application's return.
>
>:: Asset content extraction and indexing would benefit from 
>threading, and would also not require pausing the WSGI application.
>
>:: Since most templating engines aren't streaming (see my unanswered 
>thread in the general mailing list re: this), pausing the 
>application pending a particularly difficult render is a boon to 
>single-threaded async servers, though true streaming templating 
>(with flush semantics) would be the holy grail.  ;)

In all these cases, ISTM the benefit is the same if you future the 
WSGI apps themselves (which is essentially what most current async 
WSGI servers do, AFAIK).


>:: Long-duration calls to non-async-aware libraries such as DB access.
>The WSGI application could queue up a number of long DB queries, 
>pass the futures instances to the template, and the template could 
>then .result() (block) across them or yield them to be suspended and 
>resumed when the result is available.
>
>:: True async is useful for WebSockets, which seem a far superior 
>solution to JSON/AJAX polling in addition to allowing real web-based 
>socket access, of course.

The point as it relates to WSGI, though, is that there are plenty of 
mature async APIs that offer these benefits, and some of them (e.g. 
Eventlet and Gevent) do so while allowing blocking-style code to be 
written.  That is, you just make what looks like a blocking call, but 
the underlying framework silently suspends your code, without tying 
up the thread.

Or, if you can't use a greenlet-based framework, you can use a 
yield-based framework.  Or, if for some reason you really wanted to 
write continuation-passing style code, you could just use the raw Twisted API.

But in all of these cases you would be better off than if you used a 
half-implementation of the same thing using futures under WSGI, 
because all of those frameworks already have mature and sophisticated 
APIs for doing async communications and DB access.  If you try to do 
it with WSGI under the guise of "portability", all this means is that 
you are stuck rolling your own replacements for those existing APIs.

Even if you've already written a bunch of code using raw sockets and 
want to make it asynchronous, Eventlet and Gevent actually let you 
load a compatibility module that makes it all work, by replacing the 
socket API with an exact duplicate that secretly suspends your code 
whenever a socket operation would block.

IOW, if you are writing a truly async application, you'd almost have 
to be crazy to want to try to do it *portably*, vs. picking a 
full-featured async API and server suite to code against.  And if 
you're migrating an existing, previously-synchronous WSGI app to 
being asynchronous, the obvious thing to do would just be to grab a 
copy of Eventlet or Gevent and import the appropriate compatibility 
modules, not rewrite the whole thing to use futures.



More information about the Web-SIG mailing list