The split-channel package is new library that is a small variation on Control.Concurrent.Chan. The most obvious change is that it splits the channel into sending and receiving ports. This has at least two advantages: first, that this enables the type system to more finely constrain program behavior, and second, a
SendPort can have zero
ReceivePorts associated with it, and messages written to such a channel can be garbage collected.
This library started life last fall as part of my experiments in adding support for PostgreSQL’s asynchronous notifications to Chris Done’s native pgsql-simple library. The initial motivation was that if a notification arrived and nobody was listening, I wanted to be able to garbage collect it. However, the type advantages are what keep me coming back.
Beyond the primary change, this library has a number of other small improvements over
Control.Concurrent.Chan: the deprecated thread-unsafe functions aren’t there, and several operators have been added or improved, most notably
listenattaches a new
ReceivePortto an existing
Chanonly provides the ability to duplicate an existing
Edit: I was mistaken:
listenis essentially equivalent to
sendManysends a list of messages atomically. It’s a better name than
writeList2Chan, which is not atomic and is only a convenience function written in terms of
writeList2Chandoes work on infinite streams, whereas
foldis a generalization of
getChanContents, potentially avoiding some data structures.
splitcuts an existing channel into two channels. It gives you back a new
ReceivePortassociated with the existing
SendPort, and a new
SendPortassociated with the existing
ReceivePorts. This is a more general operator than one I’ve used in a few places to transparently swap out backend services.
Chandoes not provide the
splitoperator, though one could be added. However I am skeptical that this is a good idea: it’s just a little too effect-ful for comfort. I think that putting a
MVartends to be a better idea than using
split, even though it does introduce another layer of indirection.
Finally, a few acknowledgements are in order: primarily,
Control.Concurrent.Chan and its authors and contributors, and secondarily, Joey Adams for GHC Bug #5870, the fix of which has been incorporated into split-channel.