stm-sbchan-0.1: Bounded channel for STM where item sizes can vary

PortabilityRequires STM
Maintainerjoeyadams3.14159@gmail.com
Safe HaskellSafe-Infered

Data.STM.SBChan

Contents

Description

FIFO queue for STM, bounded by the total "size" of the items.

Synopsis

SBChan

data SBChan a Source

Instances

newSBChan :: Int -> STM (SBChan a)Source

Create a new, empty SBChan, with the given size limit.

To change the size limit later, use setLimitSBChan.

newSBChanIO :: Int -> IO (SBChan a)Source

IO variant of newSBChan. This is useful for creating top-level SBChans using unsafePerformIO, because performing atomically inside a pure computation is extremely dangerous (can lead to NestedAtomically errors and even segfaults, see GHC ticket #5866).

Example:

logChannel :: SBChan LogEntry
logChannel = unsafePerformIO (newSBChanIO 500000)
{-# NOINLINE logChannel #-}

Item sizes

class ItemSize a whereSource

Methods

itemSize :: a -> IntSource

Return the "size" of an individual item. This is usually an estimate of how many bytes the item takes up in memory, including channel overhead.

itemSize must return a number >= 0. itemSize should be fast, in case it is re-evaluated often due to transaction retries and invalidations.

Instances

newtype SBCItem a Source

Wrapper for items where itemSize item = 1. This helps you use SBChan as a channel with a maximum number of items.

Constructors

SBCItem 

Fields

unSBCItem :: a
 

Reading and writing

readSBChan :: ItemSize a => SBChan a -> STM aSource

Read the next item from the channel. retry if the channel is empty.

writeSBChan :: ItemSize a => SBChan a -> a -> STM ()Source

Write an item to the channel. retry if the item does not fit.

As an exception, if the channel is currently empty, but the item's size exceeds the channel limit all by itself, it will be written to the channel anyway. This is to prevent a large item from causing the application to deadlock.

peekSBChan :: SBChan a -> STM aSource

Get the next item from the channel without removing it. retry if the channel is empty.

unGetSBChan :: ItemSize a => SBChan a -> a -> STM ()Source

Put an item back on the channel, where it will be the next item read.

This will always succeed, even if it causes the channel's size limit to be exceeded. The rationale is that the size limit can be exceeded in some cases (e.g. by writing an oversized item to an empty channel). If we allow writeSBChan to exceed the limit, but don't allow unGetSBChan to exceed the limit, then we can't always read an item and put it back.

Note that unGetTBQueue in Control.Concurrent.STM.TBQueue is different: it will retry if the queue is full.

isEmptySBChan :: SBChan a -> STM BoolSource

Return True if the channel is empty.

Non-blocking variants

tryReadSBChan :: ItemSize a => SBChan a -> STM (Maybe a)Source

Variant of readSBChan which does not retry. Instead, it returns Nothing if the channel is empty.

tryWriteSBChan :: ItemSize a => SBChan a -> a -> STM BoolSource

Variant of writeSBChan which does not retry. Instead, it returns False if the item does not fit.

tryPeekSBChan :: SBChan a -> STM (Maybe a)Source

Variant of peekSBChan which does not retry. Instead, it returns Nothing if the channel is empty.

Alternative overflow strategies

cramSBChan :: ItemSize a => SBChan a -> a -> STM ()Source

Like writeSBChan, but ignore the channel size limit. This will always succeed, and will not retry.

rollSBChan :: ItemSize a => SBChan a -> a -> STM IntSource

Like writeSBChan, but if the channel is full, drop items from the beginning of the channel until there is enough room for the new item (or until the channel is empty). This will always succeed, and will not retry.

Return the number of items dropped.

Managing the limit

getLimitSBChan :: SBChan a -> STM IntSource

Get the current limit on total size of items in the channel.

setLimitSBChan :: SBChan a -> Int -> STM ()Source

Set the total size limit. If the channel exceeds the new limit, too bad.

satisfyLimitSBChan :: ItemSize a => SBChan a -> STM IntSource

Drop items from the beginning of the channel until the channel's size limit is satisfied, or until there is only one item left in the channel.

Return the number of items dropped.

Miscellaneous

clearSBChan :: SBChan a -> STM ()Source

Remove all items from the SBChan.