liblawless-0.23.0: Source/STM/Scatter.hs
{-|
Module: STM.Scatter
Description: Broadcast channel with multiple listeners and memory safety.
Copyright: © 2017 All rights reserved.
License: GPL-3
Maintainer: Evan Cofsky <evan@theunixman.com>
Stability: experimental
Portability: POSIX
-}
module STM.Scatter (
Scatter,
scatter,
scatterMsg,
Gather,
gather,
gatherMsg
)where
import Lawless
import STM.Base
import Control.Concurrent.STM.TChan
-- * The 'Scatter'
-- | A 'Scatter' is a single source that can broadcast messages
-- to any number of subscribers.
newtype Scatter a = Scatter {unScatter ∷ TChan a}
-- | Creates a new 'Scatter'.
scatter ∷ MonadBase IO m ⇒ m (Scatter a)
scatter = liftBase $ Scatter <$> newTChanIO
-- | Post a message to a 'Scatter' to all the subscribed 'Gather's.
scatterMsg ∷ MonadBase IO m ⇒ Scatter a → a → m ()
scatterMsg s a = atomically $ writeTChan (unScatter s) a
-- * The 'Gather'
-- | A 'Gather' receives copies of all messages posted to the
-- 'Scatter' it was derived from.
newtype Gather a = Gather {unGather ∷ TChan a}
-- | Create a new 'Gather' from a given 'Scatter'.
gather ∷ MonadBase IO m ⇒ Getter (Scatter a) (m (Gather a))
gather = to $ \s → Gather <$> (atomically ∘ dupTChan ∘ unScatter) s
-- | Read a message posted to a 'Gather' by a 'Scatter'.
gatherMsg ∷ MonadBase IO m ⇒ Gather a → m a
gatherMsg g = atomically $ readTChan (unGather g)