At 04:39 PM 1/9/2011 -0800, Alice BevanMcGregor wrote:
On 2011-01-09 09:26:19 -0800, P.J. Eby said:
If wsgi.input offers any synchronous methods...
Regardless of whether or not wsgi.input is implemented in an async
way, wrap it in a future and eventually get around to yielding
it. Problem /solved/.
Not the API problem. If I'm accustomed to writing synchronous code,
the async version looks ridiculous. Also, an existing WSGI web
framework isn't going to be able to be ported to this API without
putting it in a future.
My hope was for an API that would be a simple enough translation that
*everybody* could be persuaded to use it, but having to use futures
just to write a "normal" application simply isn't going to work for
the core WSGI API. As a separate "WSGI-A" profile, sure, it works fine.
If it offers only asynchronous methods, OTOH, then you can't pass
wsgi.input to any existing libraries (e.g. the cgi module).
Describe to me how a function can be suspended (other than magical
greenthreads) if it does not yield; if I knew this, maybe I wouldn't
be so confused.
I'm not sure what you're confused about. I'm the one who forgot you
have to read from wsgi.input in a blocking way to write a normal app. ;-)
(Mainly, because I was so excited about the potential in your
sketched API, and I got sucked into the process of implementing/improving it.)
I've deviated from your sketch, obviously, and any semblance of
yielding a 3-tuple. Stop thinking of my example code as conforming
to your ideas; it's a new idea, or, worst case, a narrowing of an
idea into its simplest form.
What I'm trying to point out is that you've missed two important API
enhancements in my sketch, that make it so that app and middleware
authors don't have to explicitly manage any generator methods or even
future methods.
The mechanics of yielding futures instances allows you to (in your
server) implement the necessary async code however you wish while
providing a uniform interface to both sync and async applications
running on sync and async servers. In fact, you would be able to
safely run a sync application on an async server and
vice-versa. You can, on an async server:
:: Add a callback to the yielded future to re-schedule the
application generator.
:: If using greenthreads, just block on future.result() then
immediately wake up the application generator.
:: Do other things I can't think of because I'm still waking up.
I am not sure why you're reiterating these things. The sample code I
posted shows precisely where you'd *do* them in a sync or async
server. That's not where the problem lies.
That is not optimum, because now you have an optional API that
applications who want to be compatible will need to detect and choose between.
It wasn't supposed to be optional, but it's beside the point since
the presence of a blocking API means the application can block.
The issue might be addressable by having an environment key like,
'wsgi.canblock' (indicating whether the application is already in a
separate thread/process), and a piece of middleware that simply
spawns its child app to a future if wsgi.canblock isn't set. Then
people who write blocking applications could use the decorator.
Mostly, though, it seems to me that the need to be able to write
blocking code does away with most of the benefit of trying to have
a single API in the first place.
You have artificially created this need, ignoring the semantics of
using the server-specific executor to detect async-capable requests
and the yield mechanics I suggested; which happens to be a single,
coherent API across sync and async servers and applications.
I haven't ignored them. I'm simply representing the POV of existing
WSGI apps and frameworks, which currently block, and are unlikely to
be rewritten so as not to block. I thought, briefly, that it was
possible to make an API with a low-enough conceptual overhead to
allow that porting to occur, and let my enthusiasm carry me away.
I was wrong, though: even the extremely minimalist version isn't
going to be usable for ported code, which relegates the async version
to a niche role.
I would note, though, that this is *still* better than my previous
position, which was that there was no point making an async API *at all*. ;-)
_______________________________________________
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe:
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com