[Haskell-cafe] How to make asynchronous I/O composable and safe?

Peter Simons simons at cryp.to
Sat Jan 14 12:37:15 CET 2012

Hi guys,

 >> I'm not happy with asynchronous I/O in Haskell.  It's hard to reason
 >> about, and doesn't compose well.
 > Async I/O *is* tricky if you're expecting threads to do their own
 > writes/reads directly to/from sockets. I find that using a
 > message-passing approach for communication makes this much easier.

yes, that is true. I've always felt that spreading IO code all over the
software is a choice that makes the programmers live unnecessarily hard.
The (IMHO superior) alternative is to have one central IO loop that
generates buffers of input, passes them to callback a function, and
receives buffers of output in response.

I have attached a short module that implements the following function:

  type ByteCount        = Word16
  type Capacity         = Word16
  data Buffer           = Buf !Capacity !(Ptr Word8) !ByteCount
  type BlockHandler st  = Buffer -> st -> IO (Buffer, st)

  runLoop :: ReadHandle -> Capacity -> BlockHandler st -> st -> IO st

That setup is ideal for implementing streaming services, where there is
only one connection on which some kind of dialog between client/server
takes place, i.e. an HTTP server.

Programs like Bittorrent, on the other hand, are much harder to design,
because there's a great number of seemingly individual I/O contexts
(i.e. the machine is talking to hundreds, or even thousands of other
machines), but all those communications need to be coordinated in one
way or another.

A solution for that problem invariably ends up looking like a massive
finite state machine, which is somewhat unpleasant.

Take care,

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: BlockIO.hs
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20120114/46bdf70e/attachment.txt>

More information about the Haskell-Cafe mailing list