@@ -16,11 +16,11 @@ module Periodic.Monad
16
16
, runPeriodicT
17
17
, startMainLoop
18
18
, withAgentT
19
- , newAgent
20
19
, liftPeriodicT
21
20
, isAlive
22
21
, stopPeriodicT
23
22
, env
23
+ , newAgentEnv
24
24
) where
25
25
26
26
import Control.Concurrent (forkIO )
@@ -34,32 +34,28 @@ import Control.Monad.STM (atomically)
34
34
import Control.Monad.Trans.Class (lift )
35
35
import Control.Monad.Trans.Control (MonadBaseControl , liftBaseDiscard )
36
36
import Control.Monad.Trans.Maybe (runMaybeT )
37
- import Control.Monad.Trans.Reader
37
+ import Control.Monad.Trans.Reader ( ReaderT , ask , asks , runReaderT )
38
38
import Control.Monad.Trans.State (StateT (.. ), evalStateT , get ,
39
39
gets )
40
40
import Data.ByteString (ByteString )
41
41
import qualified Data.ByteString as B (drop , empty , take )
42
42
import Periodic.Agent hiding (receive )
43
- import Periodic.Connection (ConnectionConfig , ConnectionState ,
44
- ConnectionT , close , receive ,
45
- runConnectionT )
46
- import Periodic.IOHashMap (newIOHashMap )
43
+ import Periodic.Connection (ConnectionT , close , receive )
44
+ import Periodic.IOHashMap (IOHashMap , newIOHashMap )
47
45
import qualified Periodic.IOHashMap as HM (delete , elems , insert ,
48
46
lookup , member )
49
47
import System.Entropy (getEntropy )
50
48
import System.Log.Logger (errorM )
51
49
52
50
53
51
data Env m u = Env
54
- { uEnv :: u
55
- , connectionConfig :: ConnectionConfig
56
- , agentHandler :: AgentT m ()
52
+ { uEnv :: u
53
+ , agentHandler :: AgentT m ()
57
54
}
58
55
59
56
data PeriodicState = PeriodicState
60
- { status :: TVar Bool
61
- , agentList :: AgentList
62
- , connectionState :: ConnectionState
57
+ { status :: TVar Bool
58
+ , agentList :: IOHashMap Msgid (Msgid , AgentReader )
63
59
}
64
60
65
61
type PeriodicT m u = StateT PeriodicState (ReaderT (Env m u ) (ConnectionT m ))
@@ -69,16 +65,15 @@ runPeriodicT
69
65
=> PeriodicState
70
66
-> Env m u
71
67
-> PeriodicT m u a
72
- -> m a
68
+ -> ConnectionT m a
73
69
runPeriodicT state config =
74
- runConnectionT (connectionState state) (connectionConfig config)
75
- . flip runReaderT config
70
+ flip runReaderT config
76
71
. flip evalStateT state
77
72
78
- initEnv :: MonadIO m => u -> ConnectionConfig -> Env m u
79
- initEnv u c = Env u c defaultAgentHandler
73
+ initEnv :: MonadIO m => u -> Env m u
74
+ initEnv u = Env u defaultAgentHandler
80
75
81
- initEnv_ :: u -> ConnectionConfig -> AgentT m () -> Env m u
76
+ initEnv_ :: u -> AgentT m () -> Env m u
82
77
initEnv_ = Env
83
78
84
79
defaultAgentHandler :: MonadIO m => AgentT m ()
@@ -90,32 +85,29 @@ withEnv :: (Monad m) => u1 -> PeriodicT m u1 a -> PeriodicT m u a
90
85
withEnv u m = do
91
86
state0 <- get
92
87
env0 <- lift ask
93
- liftPeriodicT $ runPeriodicT state0 (env0 {uEnv= u}) m
88
+ lift . lift $ runPeriodicT state0 (env0 {uEnv= u}) m
94
89
95
- initPeriodicState :: ConnectionState -> IO PeriodicState
96
- initPeriodicState connectionState = do
90
+ initPeriodicState :: IO PeriodicState
91
+ initPeriodicState = do
97
92
status <- newTVarIO True
98
93
agentList <- newIOHashMap
99
94
pure PeriodicState {.. }
100
95
101
96
withAgentT :: (MonadIO m , Monad m , MonadMask m ) => AgentT m a -> PeriodicT m u a
102
97
withAgentT agentT =
103
98
bracket newMsgid removeMsgid $ \ mid -> do
104
- (agentState, agentConfig ) <- newAgentEnv mid
105
- liftPeriodicT $ runAgentT agentState agentConfig agentT
99
+ (_, reader ) <- newAgentEnv_ mid
100
+ lift . lift $ runAgentT reader mid agentT
106
101
107
- newAgentEnv :: (Monad m , MonadIO m ) => Msgid -> PeriodicT m u Agent
108
- newAgentEnv mid = do
102
+ newAgentEnv_ :: (Monad m , MonadIO m ) => Msgid -> PeriodicT m u ( Msgid , AgentReader )
103
+ newAgentEnv_ mid = do
109
104
PeriodicState {.. } <- get
110
- Env {.. } <- lift ask
111
- let agentConfig = initAgentConfig mid connectionConfig
112
- agentState <- liftIO $ initAgentState connectionState
113
- liftIO $ HM. insert agentList mid (agentState, agentConfig)
114
- return (agentState, agentConfig)
115
-
116
- newAgent :: (MonadIO m , Monad m ) => PeriodicT m u Agent
117
- newAgent = newAgentEnv =<< newMsgid
105
+ reader <- liftIO $ mkAgentReader []
106
+ liftIO $ HM. insert agentList mid (mid, reader)
107
+ return (mid, reader)
118
108
109
+ newAgentEnv :: (MonadIO m ) => PeriodicT m u (Msgid , AgentReader )
110
+ newAgentEnv = newAgentEnv_ =<< newMsgid
119
111
120
112
liftPeriodicT :: (Functor m , Applicative m , Monad m ) => m a -> PeriodicT m u a
121
113
liftPeriodicT = lift . lift . lift . lift
@@ -162,14 +154,12 @@ doFeed bs = do
162
154
Env {.. } <- lift ask
163
155
v <- liftIO . HM. lookup agentList $ B. take msgidLength bs
164
156
case v of
165
- Just (agentState, agentConfig ) ->
166
- liftPeriodicT . runAgentT agentState agentConfig . feed $ B. drop msgidLength bs
157
+ Just (mid, reader ) ->
158
+ lift . lift . runAgentT reader mid . feed $ B. drop msgidLength bs
167
159
Nothing -> do
168
- let agentConfig = initAgentConfig (B. take msgidLength bs) connectionConfig
169
- agentState <- liftIO $ initAgentState connectionState
170
- liftPeriodicT . runAgentT agentState agentConfig $ do
171
- feed $ B. drop msgidLength bs
172
- agentHandler
160
+ let mid = B. take msgidLength bs
161
+ reader <- liftIO $ mkAgentReader [B. drop msgidLength bs]
162
+ lift . lift $ runAgentT reader mid agentHandler
173
163
174
164
startMainLoop
175
165
:: (MonadIO m , MonadBaseControl IO m , MonadCatch m )
@@ -189,9 +179,9 @@ isAlive = liftIO . readTVarIO =<< gets status
189
179
doFeedError :: MonadIO m => PeriodicT m u ()
190
180
doFeedError =
191
181
gets agentList >>= liftIO . HM. elems >>= mapM_ go
192
- where go :: MonadIO m => (AgentState , AgentConfig ) -> PeriodicT m u ()
193
- go (agentState, agentConfig ) =
194
- liftPeriodicT $ runAgentT agentState agentConfig $ feed B. empty
182
+ where go :: MonadIO m => (Msgid , AgentReader ) -> PeriodicT m u ()
183
+ go (mid, reader ) =
184
+ lift . lift $ runAgentT reader mid $ feed B. empty
195
185
196
186
stopPeriodicT :: MonadIO m => PeriodicT m u ()
197
187
stopPeriodicT = do
0 commit comments