[Trimming...]

On Thu, Jan 2, 2014 at 2:49 AM, Tobias Oberstein
<[email protected]> wrote:

> Interesting analogy. Yes, seems language/syntax parsing a file is similar to
> protocol parsing a wire-level stream transport. I wonder about the "sending
> leg": with language parsers, this would be probably the AST. With network
> protocols, it's more of producing a 2nd stream conforming again to the same
> "syntax": for sending to the other peer.

But reading and writing are almost always asymmetrical. E.g. for HTTP
I wouldn't see how you could reuse the push code for the input side
(say, the part that parses the headers) to write the response. The
process is just very different.

> I am wondering what happens if you take timing constraints into account. Eg.
> with WebSocket, for DoS protection, one might want to have the initial
> opening handshake finished in <N seconds. Hence you want to check after N
> seconds if state "HANDSHAKE_FINISHED" has been reached. A
>
> yield from socket.read_handshake()
>
> (simplified) will however just "block" infinitely. So I need a 2nd coroutine
> for the timeout. And the timeout will need to check .. an instance variable
> for state. Or can I have a timing out yield from?

You'd write this

  yield from asyncio.wait_for(socket.read_handshake(), <timeout_in_seconds>)

The implementation uses a Future instead of a coroutine. When the
timeout happens, the yield-from will raise asyncio.TimeoutError and
asyncio.CancelledError will be thrown into the read_handshake
coroutine (and perhaps deeper, into whatever is *actually* blocking at
this precise point).

> How would you do a pull-style UI toolkit? Transforming each push-style
> callback for UI widgets into pull-style code
>
> yield from button1.onclick()
> # handle button1 click
>
> or
>
> evt = yield from ui.onevent()
> if evt.target == "button1" and evt.type == "click":
>   # handle button1 click
>
> The latter leads to one massive, monolithic code block handling all UI
> interaction. The former leads to many small "sequential" looking code pieces
> .. similar to callbacks. And those "distributed" code pieces somehow need to
> interact with each other.

I honestly haven't figured this one out. It seems all popular UI
frameworks use push style. I recall hearing about a system called NeWS
(http://en.wikipedia.org/wiki/NeWS) that IIRC used a pull-style APIs
for a mouse-based UI. This was in the '80s, before the necessary
abstractions were widely agreed on. E.g. the mouse-tracking logic for
drawing a shape or selecting objects was done using a loop that
blocked until the mouse button was released. I don't think it was very
successful though.

> FWIW, the - for me - most comfortable and managable way of doing UI is via
> "reactive programming", e.g. in JavaScript http://knockoutjs.com/
>
> Eg. say some "x" is changing asynchronously (like a UI input field widget)
> and some "y" needs to be changed _whenever_ "x" changes (like a UI label).
>
> In reactive programming, I can basically write code
>
> y = f(x)
>
> and the reactive engine will _analyze_ that code, and hook up push-style
> callback code under the hood, so that _whenever_ x changes, f() is
> _automatically_ reapplied.

This idea has been around the block a few times too. Some of my former
colleagues on the ABC project (Python's predecessor) went on to do
something like that, and eventually their research morphed into XForms
(http://en.wikipedia.org/wiki/XForms). More recently the Elm
programming language (http://elm-lang.org/) also uses this paradigm.
I'd say it's worth knowing about and nice when it's what you need,
but, like Haskell, limited by the non-pure nature of many practical
problems.

> In fact, Twisted endpoints are so cool (sorry for mentioning this here), I
> can also run WebSocket over any stream transport, like Unix domain sockets,
> pipes, serial:
>
> https://github.com/tavendo/AutobahnPython/tree/master/examples/twisted/websocket/echo_endpoints

I'm not entirely sure what Twisted endpoints are and why they're so
cool. (Glyph kept telling me they were cool but not quite ready or
something, so I never had a good look.) But most of what you describe
here should be possible equally well with asyncio's protocol/transport
abstractions (which are pretty close to those in Twisted, if you
aren't too attached to Deferred). So what's missing?(Probably nothing
that couldn't be added on top of asyncio as a 3rd party package.)

> The thing is: the abstracted WebSocket semantics of "reliable, ordered
> datagram" neither fit TCP nor UDP.

True, but that doesn't mean it doesn't fit the datagram
transport/protocol APIs -- there's nothing in their definition that
says the underlying transport can't be reliable and ordered. :-)

> It does fit SCTP:
>
> http://en.wikipedia.org/wiki/Stream_Control_Transmission_Protocol
>
> SCTP is available natively
>
> http://www.freebsd.org/cgi/man.cgi?query=sctp&sektion=4
>
> in which case you need to use new kernel API (Posix sockets don't have it)
> and it can be layered over UDP, which is used eg with the upcoming WebRTC
> HTML5 standard:
>
> http://tools.ietf.org/html/draft-ietf-rtcweb-data-channel-06

I'm not sure that the actual implementation is relevant here --
following Twisted's example, asyncio's transports and protocols don't
require a specific underlying internet protocol. (E.g. the common
stream protocol has TCP and TLS implementations, and shares a lot of
APIs with pipes (named or unnamed).

> So I think it really could be worth to define an abstract interface in
> asyncio with the appropiate semantics for transports to implement. And
> implementing transports then could be WebSocket and SCTP or even
> shared-memory message queues ..

A concrete question: what APIs are missing in asyncio's datagram
transport and protocol classes to support SCTP and WebSocket? (Apart
from the constructor -- but the constructor is explicitly not part of
the transport/protocol abstraction, just like the __init__ signature
is not part of most ABCs.)

> Happy new year,

Same to you and anyone else who read this far!

-- 
--Guido van Rossum (python.org/~guido)

Reply via email to