{-| 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)