
The hardest part of network operations, I've found, is handling the myriad of exceptional conditions safely, in such a way that there's control over the number of sockets used and the timeouts in connections (each step potentially needs its own timeout, in fact, and one has to be careful with the interaction of asynchronous exceptions here, or move to a different sort of model) while also providing strong guarantees that resources won't leak. I.e. depending on the stage of the connection process and type of exception, different resources need to be freed. network-fancy seems to be on the right track here, but I think withSocket should absolutely take an optional timeout parameter (not for the whole action, just for the connection). I'm also not too sure that it won't leak as currently written -- i.e. if there's an error in the connection loop itself, is the socket freed? Of course something depending on the socket could still be returned out of withSocket even after its underlying socket was closed. On the other hand, if users really wanted guarantees, I think the signature of withSocket is expressive enough that iteratees could be used within the continuation it was passed. Lightweight monadic regions would also be possible as an alternate API on top of this, as a separate lib. The server functions for network-fancy also seem pretty good. Although it would be nice to have an MVar or other mechanism to shut down the servers cleanly, rather than relying on asynchronous exceptions, which might cause odd interactions. In particular, listening on sockets can likely block exceptions, which means that if you want to be able to shut down a server, you need to throw it an exception, and then ping it to force the listen call to return. Either we need some nonblocking way to listen, or that functionality needs to be wrapped up in some neat abstraction. Speaking of which, are we sure about what calls should be unsafe and safe? The small price of marking things unsafe can lead to big problems with blocking thread context switches, and thus grinding the rest of an app to a halt. A key criteria for the network library, in my opinion, should be that no network call on a given socket and thread blocks any other work of the program, including another network call on another socket and thread. Additionally, while sockets are too nitty-gritty for a high-level interface (although a socket with phantom types might not be), Handles feel to me to be too tricky to reliably map onto, and I'd much prefer something in between. Perhaps an explicit pair of a lazy bytestring and a function of type (ByteString -> IO ()) (both, of course, properly buffered.)? Of course, this doesn't map onto some of the multicast and datagram type functionality, which would need other abstractions. Cheers, S. On Aug 24, 2009, at 3:48 PM, Johan Tibell wrote:
On Mon, Aug 24, 2009 at 8:00 PM, Bryan O'Sullivan
wrote: On Fri, Aug 21, 2009 at 9:49 PM, Thomas DuBuisson
wrote: 3) Use Bytestrings (and have corrosponding .Lazy modules) for efficiency.
That's already a step up from the lowest-level bindings, which should be using Ptr a.
My plan for network-bytestring has always been to offer a Network.Socket.Buffer with function such as 'recvInto' that work on buffers. The higher level bytestring interface can then be implemented in terms of this interface.
I've been struggling a bit with how to expose less frequently used functionality in the BSD socket API such as the 'flags' parameter to 'send'. It feels a bit unfortunate to have to pass a "no flags" value in the most frequent case. Optional keyword parameters would be useful here.
4) Support more features Features such as Multicast, Header inclusion (IP_HDRINCL), address binding, etc. IOW, most the IP_ and SO_ options of socket (7) and ip (7) man pages. It would be rather nice if we were able to expose these in a friendly way - but with our cross platform concerns that might not be a good idea (e.g. I'm not familiar with windows).
Providing Network.Windows and Network.Linux and Network.BSD etc modules would work fine for non-portable platform-specific features (of which there are many).
I think this makes sense. I read some slides from a presentation on the next Java file API. The realization the Java community seemed to have come to is that you need to offer APIs with both a cross platform part and a platform specific part, preferably in such a way that both can coexist somewhat peacefully (i.e. not two completely separate class hierarchies).
Cheers,
Johan _______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries