@@ -61,34 +61,54 @@ recvQueue :: PrioritisedProcessDefinition s
6161 -> Queue
6262 -> Process ExitReason
6363recvQueue p s t q =
64- let pDef = processDef p
65- ps = priorities p
66- handleStop = shutdownHandler pDef
67- in do
68- (ac, d, q') <- processNext pDef ps s t q
69- case ac of
70- (ProcessContinue s') -> recvQueueAux p ps s' d q'
71- (ProcessTimeout t' s') -> recvQueueAux p ps s' t' q'
72- (ProcessHibernate d' s') -> block d' >> recvQueueAux p ps s' d q'
73- (ProcessStop r) -> handleStop s r >> return (r :: ExitReason )
74- (ProcessStopping s' r) -> handleStop s' r >> return (r :: ExitReason )
64+ let pDef = processDef p
65+ ps = priorities p
66+ in do (ac, d, q') <- catchExit (processNext pDef ps s t q)
67+ (\ _ (r :: ExitReason ) ->
68+ return (ProcessStop r, Infinity , q))
69+ nextAction ac d q'
7570 where
76- recvQueueAux :: PrioritisedProcessDefinition s
77- -> [DispatchPriority s ]
78- -> s
79- -> Delay
80- -> Queue
81- -> Process ExitReason
82- recvQueueAux ppDef prioritizers pState delay queue = do
83- t' <- startTimer delay
84- drainMessageQueue pState prioritizers queue >>= recvQueue ppDef pState t'
71+ nextAction ac d q'
72+ | ProcessContinue s' <- ac = recvQueueAux p (priorities p) s' d q'
73+ | ProcessTimeout t' s' <- ac = recvQueueAux p (priorities p) s' t' q'
74+ | ProcessHibernate d' s' <- ac = block d' >> recvQueueAux p (priorities p) s' d q'
75+ | ProcessStop r <- ac = (shutdownHandler $ processDef p) s r >> return r
76+ | ProcessStopping s' r <- ac = (shutdownHandler $ processDef p) s' r >> return r
77+ | otherwise {- compiler foo -} = die " IllegalState"
78+
79+ recvQueueAux ppDef prioritizers pState delay queue =
80+ let ex = (trapExit: (exitHandlers $ processDef ppDef))
81+ eh = map (\ d' -> (dispatchExit d') pState) ex
82+ in (do t' <- startTimer delay
83+ mq <- drainMessageQueue pState prioritizers queue
84+ recvQueue ppDef pState t' mq)
85+ `catchExit`
86+ (\ pid (reason :: ExitReason ) -> do
87+ let pd = processDef ppDef
88+ let ps = pState
89+ let pq = queue
90+ let em = unsafeWrapMessage reason
91+ (a, d, q') <- findExitHandlerOrStop pd ps pq eh pid em
92+ nextAction a d q')
93+
94+ findExitHandlerOrStop :: ProcessDefinition s
95+ -> s
96+ -> Queue
97+ -> [ProcessId -> P. Message -> Process (Maybe (ProcessAction s ))]
98+ -> ProcessId
99+ -> P. Message
100+ -> Process (ProcessAction s , Delay , Queue )
101+ findExitHandlerOrStop _ _ pq [] _ er = do
102+ mEr <- unwrapMessage er :: Process (Maybe ExitReason )
103+ case mEr of
104+ Nothing -> die " InvalidExitHandler" -- TODO: better error message?
105+ Just er' -> return (ProcessStop er', Infinity , pq)
106+ findExitHandlerOrStop pd ps pq (eh: ehs) pid er = do
107+ mAct <- eh pid er
108+ case mAct of
109+ Nothing -> findExitHandlerOrStop pd ps pq ehs pid er
110+ Just pa -> return (pa, Infinity , pq)
85111
86- processNext :: ProcessDefinition s
87- -> [DispatchPriority s ]
88- -> s
89- -> TimeoutSpec
90- -> Queue
91- -> Process (ProcessAction s , Delay , Queue )
92112 processNext def ps' pState tSpec queue =
93113 let ex = (trapExit: (exitHandlers def))
94114 h = timeoutHandler def in do
@@ -109,10 +129,6 @@ recvQueue p s t q =
109129 (map (\ d' -> (dispatchExit d') s') ex)
110130 return (act, t', q')
111131
112- processApply :: ProcessDefinition s
113- -> s
114- -> P. Message
115- -> Process (ProcessAction s )
116132 processApply def pState msg =
117133 let pol = unhandledMessagePolicy def
118134 apiMatchers = map (dynHandleMessage pol pState) (apiHandlers def)
@@ -121,24 +137,13 @@ recvQueue p s t q =
121137 ms' = (shutdown': apiMatchers) ++ infoMatchers
122138 in processApplyAux ms' pol pState msg
123139
124- processApplyAux :: [(P. Message -> Process (Maybe (ProcessAction s )))]
125- -> UnhandledMessagePolicy
126- -> s
127- -> P. Message
128- -> Process (ProcessAction s )
129140 processApplyAux [] p' s' m' = applyPolicy p' s' m'
130141 processApplyAux (h: hs) p' s' m' = do
131142 attempt <- h m'
132143 case attempt of
133144 Nothing -> processApplyAux hs p' s' m'
134145 Just act -> return act
135146
136- drainOrTimeout :: s
137- -> Delay
138- -> Queue
139- -> [DispatchPriority s ]
140- -> TimeoutHandler s
141- -> Process (ProcessAction s , Delay , Queue )
142147 drainOrTimeout pState delay queue ps' h = do
143148 let matches = [ matchMessage return ]
144149 recv = case delay of
0 commit comments