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

Daniel Waterworth da.waterworth at gmail.com
Sat Jan 14 12:33:03 CET 2012


Disregard that last comment on `TChan`s; retry blocks. you learn a new
thing every day [=

Daniel

On 14 January 2012 11:27, Daniel Waterworth <da.waterworth at gmail.com> wrote:
> 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