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

Daniel Waterworth da.waterworth at gmail.com
Sat Jan 14 12:27:17 CET 2012


I've been trying to write networking code in Haskell too. I've also
come to the conclusion that channels are the way to go. However,
what's missing in the standard `Chan` type, which is essential for my
use-case, is the ability to do the equivalent of the unix select call.
My other slight qualm is that the type doesn't express the direction
of data (though this is easy to add afterwards).

I know of the chp package, but in order to learn how it worked, I
spent a day writing my own version. I've kept the API similar to that
of the standard Chan's. If it would be useful to you as well, I'll
happily open source it sooner rather than later,

Daniel

p.s I'd avoid the TChan for networking code as reading from a TChan is
a busy operation. [1]

[1] http://hackage.haskell.org/packages/archive/stm/2.2.0.1/doc/html/src/Control-Concurrent-STM-TChan.html#readTChan

On 14 January 2012 10:42, Joey Adams <joeyadams3.14159 at gmail.com> wrote:
> On Sat, Jan 14, 2012 at 1:29 AM, Bardur Arantsson <spam at scientician.net> wrote:
>> So, the API becomes something like:
>>
>>   runSocketServer :: ((Chan a, Chan b) -> IO ()) -> ... -> IO ()
>>
>> where the first parameter contains the "client logic" and "A" is the type of
>> the messages from the client and "B" is the type of the messages which are
>> sent back to the client.
>
> Thanks, that's a good idea.  Even if I only plan to receive in one
> thread, placing the messages in a Chan or TChan helps separate my
> application thread from the complexities of connection management.
>
> Is there something on Hackage that will do this for me?  Or will I
> need to roll my own?  Namely, convert a network connection to a pair
> of channels, and close the connection automatically.  Something like
> this:
>
>    -- | Spawn two threads, one which populates the first channel with messages
>    -- from the other host, and another which reads the second channel and sends
>    -- its messages to the other host.
>    --
>    -- Run the given computation, passing it these channels.  When the
> computation
>    -- completes (or throws an exception), sending and receiving will
> stop, and the
>    -- connection will be closed.
>    --
>    -- If either the receiving thread or sending thread encounter an exception,
>    -- sending and receiving will stop, and an asynchronous exception will be
>    -- thrown to your thread.
>    channelize :: IO msg_in             -- ^ Receive callback
>                   -> (msg_out -> IO ()     -- ^ Send callback
>                   -> IO ()                 -- ^ Close callback
>                   -> (TChan msg_in -> TChan msg_out -> IO a)
>                                            -- ^ Inner computation
>                   -> IO a
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe



More information about the Haskell-Cafe mailing list