module Eventloop.System.SenderThread where
import Control.Exception
import Control.Monad
import Control.Concurrent.STM
import Control.Concurrent.Datastructures.BlockingConcurrentQueue
import Eventloop.Types.Common
import Eventloop.Types.Events
import Eventloop.Types.Exception
import Eventloop.Types.System
startSending :: EventloopSystemConfiguration progstateT
-> (EventloopModuleConfiguration, EventloopModuleSenderConfiguration)
-> IO ()
startSending systemConfig (moduleConfig, moduleSenderConfig)
= forever $ do
outEvent <- takeFromBlockingConcurrentQueue senderEventQueue_
case outEvent of
Stop -> do
sendOne moduleId_ sharedConst sharedIOT ioConst ioStateT_ sender_ Stop
throwIO RequestShutdownException
_ -> sendOne moduleId_ sharedConst sharedIOT ioConst ioStateT_ sender_ outEvent
where
moduleId_ = moduleId moduleConfig
sharedConst = sharedIOConstants systemConfig
sharedIOT = sharedIOStateT systemConfig
ioConst = ioConstants moduleConfig
ioStateT_ = ioStateT moduleConfig
sender_ = sender moduleSenderConfig
senderEventQueue_ = senderEventQueue moduleSenderConfig
sendOne :: EventloopModuleIdentifier
-> SharedIOConstants
-> TVar SharedIOState
-> IOConstants
-> TVar IOState
-> EventSender
-> Out
-> IO ()
sendOne moduleId sharedConst sharedIOT ioConst ioStateT sender outEvent
= handle ( \exception ->
case (fromException exception) of
(Just ShuttingDownException) -> throwIO ShuttingDownException
_ -> throwIO (SendingException moduleId outEvent exception)
)
( sender sharedConst sharedIOT ioConst ioStateT outEvent
)