[swift-server-dev] Sockets API
hatsuneyuji at icloud.com
Thu Oct 27 14:07:35 CDT 2016
I have some thought about how socket should be implemented.
I think libdispatch is maybe too high-level if we are working on a socket framework we should work on just socket for the following reasons:
1. It take care of too many things.
Most of the framework exist today using different event-looping/threading model. Some is using a listening thread and delegate works to worker threads, some is using traditional single threaded kevent/epoll to prevent callback hell, me myself use multiple threads and each thread has its own event looping etc.
2. libdispatch make it hard to implement some protocols such as TLS, where you delegate the TLS frameworks(openssl/libressl) to handle TLS handshake, sending/writing. These frameworks require a real file descriptor to work.
3. I think the a fundamental socket framework should not use either delegate nor closure, but a overridable read() -> Data and write() function instead. Socket in general has a pretty short lifetime, if we use closure and delegate it will be harder to manage the lifetime of related objects. Such as if I open a separate unix socket to connect to some database, however the network socket closed before the response from database socket even arrived.
Having an overridable read/write method can have following advantages:
- provide socket level optimization (sendfile, TCP_CORK, TCP_NOPUSH, etc)
- static, prevent callback hell
- make a socket independent.
I think we can take advantage of swift as a protocol oriented language and make a “SocketType" protocol, which will give us the following benefits:
A C socket is fundamentally not “type safe”, there are socket binded with struct sockaddr, stream socket which can connect(), listen(), accept(), dgram sockets that cannot do such. making sockets confirm to a protocol can solve all these issue by let different kind of sockets to define different ways to approach the overall behavior we expected. And this also make the purpose of each socket much more cleaner by having different type name.
Some protocol act like another socket layer, such as TLS, by having a socket as a protocol we can define a high-level socket such as TLSSocket that when we read/write from it it will act like a normal socket. Which effectively abstract complicated protocol away from users
By having different sockets generically different type but same protocol we simply can avoid a lot of dynamic checking in runtime.
> On Oct 27, 2016, at 04:23, Helge Heß via swift-server-dev <swift-server-dev at swift.org> wrote:
> On 27 Oct 2016, at 00:12, Logan Wright via swift-server-dev <swift-server-dev at swift.org> wrote:
>> Sticking w/ the direction of the doc and working upwards, TCP and general socket work seems to be a natural starting point to work with.
>> - Logan
> I think people first had to figure out what this is all about. Maybe a swift-server-discuss mailing list is still valuable.
> # Starting Point: Sockets
> First of all I wonder whether this really belongs into Foundation, not swift-server-dev? It sounds like a generic Foundation feature which is as useful on the client. Or is it going to be developed here and moved over when ready?
> Anyways, so what do people expect from a low level sockets API. There are a lot of design choices. To name a few:
> 1) Should it be synchronous (potentially w/ a non-blocking mode) and
> essentially just wrapping the Posix (and later) API?
> 2) Should it be asynchronous?
> - does everyone agree that async I/O would be driven by
> libdispatch channels?
> - and that data would be handed back-n-forth using DispatchData?
> - if it is async, ‘Swifty’ API for error handling does not really
> exist, i.e. no throws/try etc
> - so what should error handling look like?
> - should it use escaping closures for callbacks or delegates
> 3) Do you really want just a Socket, or is what you really want
> a (byte) stream framework?
> - there are some specifics to sockets (timeouts, connects and
> such), but the core of reading/writing(/encrypting/hashing/..)
> byte blocks/vectors is a general concept
> - this also affects TLS support (which wraps the reading/writing)
> - in the context of a potential core HTTP module, would requests
> and responses be exposed as streams with the same API?
> - think about chunked and WebSocket/Upgrade here
> - or would the HTTP API be completely separate?
> - would you want to have piping? (say, stream a file to a socket
> and through a zip stream)
> - would it handle back pressure?
> - consider optimisations for FD based streams (to use sendfile()
> and such)
> 4) Does it need String support or just bytes?
> - in a way java.io.Reader/Writer vs java.io.xyzStream
> I would be interested to hear some ideas on where people think this would be going :-)
> swift-server-dev mailing list
> swift-server-dev at swift.org
More information about the swift-server-dev