On Sat, Jan 4, 2014 at 11:33 AM, Tobias Oberstein <[email protected]> wrote: [endpoints] > My understanding: they completely decouple the creation of application > specific factories/protocols from the creation of network clients/servers > using the former and created from "client/server string descriptors". > > Clients/servers can be created from string descriptors. This allows to write > programs that let users determine on command line whether to use eg TCP, > Unix domain socket or even Serial. [...] > What's missing is probably something like this (which I guess could be added > to asyncio): > > coro = loop.create_server(EchoServer, stream_server_descriptor) > > where > > stream_server_descriptor = "tcp:127.0.0.1:8000" > > or > > stream_server_descriptor = "unix:/tmp/myserver"
OK, that makes some sense, but it can easily be added as a 3rd party add-on. (And eventually integrated back.) I've added this idea to the Tulip tracker: http://code.google.com/p/tulip/issues/detail?id=97 (Oh, I just saw Glyph replied to the same question. I may have to update that tracker item. :-) This is similar to the URL-ish syntax I've seen in database drivers for specifying the database server. I suppose we could support the Twisted syntax (if it's documented well enough) or make up our own, possibly borrowing from URLs (which are another variant of the same idea). >> A concrete question: what APIs are missing in asyncio's datagram >> transport and protocol classes to support SCTP and WebSocket? (Apart > DatagramProtocol.datagram_received and DatagramTransport.sendto take an > `addr` parameter. > > However, SCTP and WebSocket are _connected_ protocols. On UNIX, UDP can also be connected, and Tulip supports this. :-) > Hence, there isn't anything missing actually, but `addr` is in excess. > > So for sendto, the addr would either needed to be ignored, or raised when > non-None. If you specify a destination in when creating the datagram connection that's exactly how it works. > And for datagram_received, the addr would either be the fixed addr of the > connected peer, or be set None. Right. > As a corollary: how is addr handled with connected UDP? Um, yes. :-) > FWIW: https://twistedmatrix.com/documents/current/core/howto/udp.html#auto3 > > Finally: yes, syntactically, there is nothing which would distinguish an > ordered, reliable datagram interface from and unordered, unreliable datagram > interface (at least a connected one). > > Mmh, but shouldn't the interface _identity_ also express semantics? That seems an idea from Twisted. I don't want to go that way. I prefer giving the transport object an inquiry method if necessary; that's how asyncio does it for the capability to use write_eof() (which works for TCP but not for SSL/TLS). > If I get a transport, and want to adjust behavior according to whether the > transport is unreliable, even today I am not supposed to do that > via isinstance(transport, DatagramTransport), since DatagramTransport > doesn't imply any semantics, but only specifies a programmatic interface (on > a syntactical level)? You're already writing your protocol code specific to either a datagram or a stream transport, because the protocol API is (intentionally) different. So there's never a question about which kind of transport you have. > And a transport deriving from asyncio.transport.Transport (a stream) might > be in fact unreliable? I don't see any useful semantics for that. > What are the exact semantics implied by Transport and DatagramTransport - > beyond the mere existence of certain functions syntactically? You probably have to ask a more specific question. The datagram API promises that if the sender sends two packets, and both arrive, the receiver will see two packets, though not necessarily in the same order (and one or both may be lost). The stream API promises that the receiver sees the bytes that the sender sent, in the same order, until the connection is terminated or broken, but it makes no promises about whether you'll get a separate data_received() call for each byte or a single call for all bytes. In particular there's no promise that the framing implied by the sender's sequence of send() or write() calls is preserved -- the network may repackage the bytes in arbitrary blocks. By the way, there's nothing that would prevent you from defining your own transport and protocol ABCs. -- --Guido van Rossum (python.org/~guido)
