[Web-SIG] Server-side async API implementation sketches
Alice Bevan–McGregor
alice at gothcandy.com
Sun Jan 9 12:01:12 CET 2011
On 2011-01-08 20:06:19 -0800, Alex Grönholm said:
> I liked the idea of having a separate async_read() method in
> wsgi.input, which would set the underlying socket in nonblocking mode
> and return a future. The event loop would watch the socket and read
> data into a buffer and trigger the callback when the given amount of
> data has been read. Conversely, .read() would set the socket in
> blocking mode. What kinds of problems would this cause?
Manipulating the underlying socket is potentially dangerous
(pipelining) and, in fact, not possible AFIK while being
PEP444-compliant. When the request body is fully consumed, additional
attempts to read _must_ return empty strings. Thus raw sockets are
right out at a high level; internal to the reactor this may be
possible, however. It'd be interesting to adapt marrow.io to using
futures in this way as an experiment.
OTOH, if you utilize callbacks extensively (as m.s.http does) you run
into the problem of data passing. Your application is called (wrapped
in middleware), sets up some futures and callbacks, then returns. No
returned data. Middleware just got shot in the foot. The server,
also, got shot in the foot. How can it get a resopnse tuple back from
a callback? How can middleware be utilized? That's a weird problem to
wrap my head around. Blocking the application pending the results of
various socket operations is something that would have to be mandated
to avoid this issue. :/
Multiple in-flight reads would also be problematic; you may end up with
buffer interleaving issues. (e.g. job A reads 128 bytes at a time and
has been requested to return 4KB, job B does the same... what happens
to the data?) Then you begin to involve locking...
Notice that my write_body method [1], writes using async, passing the
iterable to the callback which is itself. This is after-the-fact
(after the request has been returned) and is A-OK, though would need to
be updated heavily to support the ideas of async floating around right
now. I'm also extremely careful to never have multiple async callbacks
pending (and thus never have muliple "jobs" for a single connection
working at once).
- Alice.
[1]
https://github.com/pulp/marrow.server.http/blob/draft/marrow/server/http/protocol.py#L313-332
More information about the Web-SIG
mailing list