------------------------------------------------------------------------------ -- | -- Module : Control.Concurrent.Chan.Split -- Copyright : (c) 2012 Leon P Smith -- License : MIT -- -- Maintainer : leon@melding-monads.com -- -- This package provides an unbounded, imperative queue that is supposed to -- be thread safe and asynchronous exception safe. It is essentially the -- same communication mechanism as 'Control.Concurrent.Chan.Chan', except -- that each channel is split into separate sending and receiving ends, -- called 'SendPort' and 'ReceivePort' respectively. This has at least two -- advantages: -- -- 1. Program behavior can be more finely constrained via the type system. -- -- 2. Channels can have zero @ReceivePorts@ associated with them. Messages -- written to such a channel disappear into the aether and can be -- garbage collected. Note that @ReceivePorts@ can be subsequently -- attached to such a channel via 'listen', and can be detached via -- garbage collection. -- -- By contrast, 'Control.Concurrent.Chan.Chan' couples a @SendPort@ and -- a @ReceivePort@ together in a pair. Thus keeping a reference to a -- @SendPort@ implies that there is at least one reference to a -- @ReceivePort@, which means that messages cannot be garbage collected -- from an active channel if nobody is listening. -- -- A channel can have multiple @ReceivePorts@. This results in a publish- -- subscribe pattern of communication: every message will be delivered to -- every port. Alternatively, multiple threads can read from a single -- port. This results in a push-pull pattern of communication, similar to -- ZeroMQ: every message will be delivered to exactly one thread. Of -- course both can be used together to form hybrid patterns of -- communication. -- -- A channel can only have one @SendPort@. However multiple threads can -- can safely write to a single port, allowing effects similar to multiple -- @SendPorts@. -- -- Some of the tradeoffs of @split-channel@ compared to Cloud Haskell's -- @Remote.Channel@ are: -- -- 1. @split-channel@ is restricted to in-process communications only. -- -- 2. @split-channel@ has no restriction on the type of values that may be -- communicated. -- -- 3. There is a quasi-duality between the two approaches: Cloud Haskell's -- @ReceivePorts@ are special whereas @split-channel@'s @SendPorts@ are -- special. -- -- 4. @ReceivePorts@ can be @'duplicate'd@, which allows for considerably -- more efficient publish-subscribe communications than supported by -- Cloud Haskell at the present time. -- ------------------------------------------------------------------------------ module Control.Concurrent.Chan.Split ( SendPort , ReceivePort , new , newSendPort , send , receive , sendMany , listen , duplicate , split , fold , unsafeFold ) where import Control.Concurrent.Chan.Split.Implementation