courier-0.1.0.10: A message-passing library for simplifying network applications

Portabilitynon-portable (uses STM)
Stabilityexperimental
Maintainerphil@haphazardhouse.net
Safe HaskellSafe-Inferred

Control.Concurrent.Mailbox

Contents

Description

A Mailbox is a drop-in replacement for TQueue in Control.Concurrent.STM, except that it also supports selective out of order message reception: that is, it allows the caller to dequeue the first message among the messages available in the queue that matches a supplied test function, or block if no such match is possible with the messages currently in the queue.

As Mailbox implements the same basic read write peek group of functions as a TQueue, it offers a superset of TQueue functionality by extending it with the find select handle groups of functions. Thus, applications can safely use Mailboxes in place of TQueues, but choose when to take the slight extra overhead of Mailbox functionality.

Because message selection in worst case requires fully traversing all messages in the queue, application designers are encouraged to understand this aspect when choosing to use Mailboxes in their designs, or when using the additional features of Mailboxes beyond that of TQueues. Dispatching messages with a Mailbox is analogous to using a case expression (O(n)) to dispatch messages to a handler function, except that new cases can be added or removed at any time. In essence, one can regard Mailboxes as a useful means of creating an extensible message dispatch function. If, however, if O(1) message dispatching time is necessary or desired, (using hashmaps, for example) then Mailboxes are not the correct choice.

Despite this extra cost, Mailboxes offer advantages to designers:

  • Implementation of Erlang-style message reception: as messages can be received out of order, a mailbox is analogous to a process input queue in Erlang.
  • Better composability: if applications must only dequeue messages in the order in which they are queued (which is sufficient for many applications), then the main message pump requires modification each time a new class of message must be handled. With selective message reception, multiple concurrent message pumps are possible (with a small performance impact), each processing the messages they expect and with no need to be aware of other message pumps performing their own work on the same mailbox.
  • Mixing synchronous and asynchronous programming styles: if restricted to in order message delivery, an application must carefully construct all logic to avoid blocking its central message loop. By supporting out of message delivery and multiple selective recipients, it becomes possible to combine synchronous and asynchronous programming styles using the same Mailbox.

Basic framework for Mailbox brazenly copied from Control.Concurrent.STM.TQueue.

Synopsis

Mailbox

data Mailbox m Source

Instances

Eq (Mailbox m) 

newMailbox :: STM (Mailbox m)Source

Build and returns a new instance of Mailbox

newMailboxIO :: IO (Mailbox m)Source

IO version of newMailbox. This is useful for creating top-level Mailboxs using unsafePerformIO, because using atomically inside unsafePerformIO isn't possible.

writeMailbox :: Mailbox m -> m -> STM ()Source

Write a value to a Mailbox.

readMailbox :: Mailbox m -> STM mSource

Read the next value from the Mailbox.

tryReadMailbox :: Mailbox m -> STM (Maybe m)Source

A version of readMailbox which does not retry. Instead it returns Nothing if no value is available.

peekMailbox :: Mailbox m -> STM mSource

Get the next value from the Mailbox without removing it, retrying if the channel is empty.

tryPeekMailbox :: Mailbox m -> STM (Maybe m)Source

A version of peekMailbox which does not retry. Instead it returns Nothing if no value is available.

selectMailbox :: Mailbox m -> (m -> Maybe v) -> STM vSource

Find the next message in the mailbox that matches the supplied test function or block until there is a message that does. When a message matches (e.g., test functions returns Just v), return it.

trySelectMailbox :: Mailbox m -> (m -> Maybe v) -> STM (Maybe v)Source

A version of selectMailbox which does not retry. Instead it returns Nothing if no value is available.

handleMailbox :: Mailbox m -> (m -> Maybe v) -> (v -> IO r) -> IO rSource

Wait until there is a message in the mailbox matching the supplied test function (using selectMailbox), then when a message is found, handle it in the IO monad with the supplied function.

findMailbox :: Mailbox m -> (m -> Maybe v) -> STM vSource

Find the next value from the Mailbox matching testFn without removing it, retrying if the channel is empty.

tryFindMailbox :: Mailbox m -> (m -> Maybe v) -> STM (Maybe v)Source

A version of findMailbox which does not retry. Instead it returns Nothing if no value is available.

unGetMailbox :: Mailbox m -> m -> STM ()Source

Put a data item back onto a channel, where it will be the next item read.

isEmptyMailbox :: Mailbox m -> STM BoolSource

Returns True if the supplied Mailbox is empty.