[Web-SIG] [PEP 444] Future- and Generator-Based Async Idea

Paul Davis paul.joseph.davis at gmail.com
Sat Jan 8 19:24:56 CET 2011


On Sat, Jan 8, 2011 at 6:26 AM, Alice Bevan–McGregor
<alice at gothcandy.com> wrote:
> Warning: this assumes we're running on bizzaro-world PEP 444 that mandates
> applications are generators.  Please do not dismiss this idea out of hand
> but give it a good look and maybe some feedback.  ;)
>
> --
>
> Howdy!
>
> I've finished touching up the p-code illustrating my idea of using
> generators to implement async functionality within a WSGI application and
> middleware, including the idea of a wsgi2ref-supplied decorator to simplify
> middleware.
>
>        https://gist.github.com/770743
>
> There may be a few typos in there; I switched from the idea of passing back
> the returned value of the future to passing back the future itself in order
> to better handle exception handling (i.e. not requiring utter insanity in
> the middleware to determine the true source of an exception and the need to
> pass it along).
>
> The second middleware demonstration (using a decorator) makes middleware
> look a lot more like an application: yielding futures, or a response, with
> the addition of yielding an application callable not explored in the first
> (long, but trivial) example.  I believe this should cover 99% of middleware
> use cases, including interactive debugging, request routing, etc. and the
> syntax isn't too bad, if you don't mind standardized decorators.
>
> This should be implementable within the context of Marrow HTTPd
> (http://bit.ly/fLfamO) without too much difficulty.
>
> As a side note, I'll be adding threading support to the server (actually,
> marrow.server, the underlying server/protocol abstraction m.s.http utilizes)
> using futures some time over the week-end by wrapping the async callback
> that calls the application with a call to an executor, making it immune to
> blocking, but I suspect the overhead will outweigh the benefit for speedy
> applications.
>
> Testing multi-process vs. multi-threaded using 2 workers each and the prime
> calculation example, threading is 1.5x slower for CPU-intensive tasks under
> Python 2.7.  That's terrible.  It should be 2x; I have 2 cores.  :/
>
>        - Alice.
>
>
> _______________________________________________
> Web-SIG mailing list
> Web-SIG at python.org
> Web SIG: http://www.python.org/sigs/web-sig
> Unsubscribe:
> http://mail.python.org/mailman/options/web-sig/paul.joseph.davis%40gmail.com
>

For contrast, I thought it might be beneficial to have a comparison
with an implementation that didn't use async might look like:

http://friendpaste.com/4lFbZsTpPGA9N9niyOt9PF

If your implementation requires that people change source code (yield
vs return) when they move code between sync and async servers, doesn't
that pretty much violate the main WSGI goal of portability?

IMO, the async middleware is quite more complex than the current state
of things with start_response. The ability to subtly miss invoking the
generator, or invoking it too many times and dropping part of a
response. Forcing every middleware to unwrap iterators and handle
their own StopExceptions is worrisome as well.

I can't decide if casting the complexity of the async middleware as a
side benefit of discouraging authors was a joke or not.

Either way this proposal reminds me quite a bit of Duff's device [1].
On its own Duff's device is quite amusing and could even be employed
in some situations to great effect. On the other hand, any WSGI spec
has to be understandable and implementable by people from all skill
ranges. If its a spec that only a handful of people comprehend, then I
fear its adoption would be significantly slowed in practice.


[1] http://en.wikipedia.org/wiki/Duff's_device


More information about the Web-SIG mailing list