[Cross posted between the source of the discussion and the Web-SIG for
additional discussion there.]
On 2011-03-15 14:54:18 -0700, Mike Orr said:
There has been an ongoing discussion between the WSGI developers and
Twisted about how to be more compatible. The upshot is that
asynchronous servers need some kind of token in the output stream that
means "I'm not ready; come back later." Other middleware would have to
pass this token through unchanged. And of course, the application would
have to use non-blocking libraries such as non-blocking database
executors. I'm not sure if ordinary file access is "blocking" enough to
require that too.
Not just Twisted; have a gander at the Web-SIG mailing list for
December and January.[1]
Unfortunately the amount of interconnectedness (and thus complexity)
needed for a working solution takes the concept of async completely out
of the domain of a low-level specification like WSGI.
An "I'm not ready; come back later" token, which in marrow.server.http
is already implemented—yield None from your body iterator—would, as an
example, add an immediate (or slightly delayed) callback in the
reactor[2] which will then poll the application for real data. That's
not async; that's no better than AJAX polling! (And is unidirectional
to boot.)
Non-blocking libraries… how do they determine how to be non-blocking?
Socket and file operations, which can be easily made non-blocking
through the use of select/epoll/kqueue/libevent/libev, have the
distinction of being handled (and likely already used) at the WSGI
server's reactor level. How would a third-party library interface to
an existing reactor in an agnostic way? I'm fairly confident that it
just wouldn't be feasible.
If non-blocking libraries implemented their own async reactors… how
would you coordinate the mess of having, potentially, half a dozen
reactors?
Futures objects take some of the headache away, allowing for the WSGI
application to ask for some work to be performed by a third-party
library, returning a Future, then being suspended pending the result of
the Future. Futures are easy to detect (through duck typing) and can
be easily ignored (and passed along) by middleware.
Still, Futures are usually bound to an Executor (reactor), and that
executor instance would need to be passed to the third-party libraries
somehow. marrow.server.http provides a 'wsgi.executor' environment
variable which is, usually, a thread pool worker, which still doesn't
quite qualify for async status.
A PEP extending Futures for use with true async models would be a great
start, and could likely be combined with a simple extension to WSGI to
add the appropriate environment variables. Alex Grönholm, Graham
Dumpleton, everyone on the (excellent, if lacking in bloody combat ;)
WSGI panel at PyCon, and I seem to all agree that async has no part in
core WSGI. There would simply be no way to get a consensus on a single
API with so many disparate implementations already in the wild.
The upshot has been that Twisted runs WSGI applications in a thread
anyway because it can't be sure they won't block.
As does marrow.server.http if requested to do so. Extremely small or
efficient applications can choose not to.
And there hasn't been enough interest from WSGI developers to actually
pursue using it with asynchronous servers.
I've been interested, as has my partner in crime. We've actually
fiddled around with futures-based core IO reactors, different return /
yield styles for WSGI applications, and all sorts of crazy things, and
always came to the same conclusion. :(
I think Python has a future object now which standardizes Twisted's
Deferred and the equivalent in other asynchronous servers. So that's a
start.
The core Futures implementation (concurrent.futures; core in Python 3.2
with a portable back-port maintained, I believe, by Alex) utilizes a
thread pool or process pool, has referential limitations (i.e. don't
pass the executor to a future running in a process pool… deadlocks are
bad), and I simply have no idea at this time how difficult it would be
to create a true async reactor under that model.
The end result of all of this is that async support should be its own
PEP, extending WSGI (333, now 3333) and potentially extending Futures,
PEP 3148[3], to create an acceptable generalized API for async
interfaces, not just worker pools. I've abandoned the idea for my own
WSGI 2 WIP, PEP 444[3], which marrow.server.http is the reference
implementation (and idea sandbox) of/for.
— Alice.
P.s. If anyone has information I don't have, or simply can't remember
at midnight after a very long day, feel free to correct me! :)
[1] http://mail.python.org/pipermail/web-sig/
[2] I know, 'reactor' isn't exactly an accurate term. I just can't
remember the right one right now.
[3] http://www.python.org/dev/peps/pep-3148/
[4] http://bit.ly/fRyMJ2
--
You received this message because you are subscribed to the Google Groups
"pylons-devel" group.
To post to this group, send email to pylons-devel@googlegroups.com.
To unsubscribe from this group, send email to
pylons-devel+unsubscr...@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/pylons-devel?hl=en.