@@ -61,34 +61,54 @@ recvQueue :: PrioritisedProcessDefinition s
61
61
-> Queue
62
62
-> Process ExitReason
63
63
recvQueue 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'
75
70
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)
85
111
86
- processNext :: ProcessDefinition s
87
- -> [DispatchPriority s ]
88
- -> s
89
- -> TimeoutSpec
90
- -> Queue
91
- -> Process (ProcessAction s , Delay , Queue )
92
112
processNext def ps' pState tSpec queue =
93
113
let ex = (trapExit: (exitHandlers def))
94
114
h = timeoutHandler def in do
@@ -109,10 +129,6 @@ recvQueue p s t q =
109
129
(map (\ d' -> (dispatchExit d') s') ex)
110
130
return (act, t', q')
111
131
112
- processApply :: ProcessDefinition s
113
- -> s
114
- -> P. Message
115
- -> Process (ProcessAction s )
116
132
processApply def pState msg =
117
133
let pol = unhandledMessagePolicy def
118
134
apiMatchers = map (dynHandleMessage pol pState) (apiHandlers def)
@@ -121,24 +137,13 @@ recvQueue p s t q =
121
137
ms' = (shutdown': apiMatchers) ++ infoMatchers
122
138
in processApplyAux ms' pol pState msg
123
139
124
- processApplyAux :: [(P. Message -> Process (Maybe (ProcessAction s )))]
125
- -> UnhandledMessagePolicy
126
- -> s
127
- -> P. Message
128
- -> Process (ProcessAction s )
129
140
processApplyAux [] p' s' m' = applyPolicy p' s' m'
130
141
processApplyAux (h: hs) p' s' m' = do
131
142
attempt <- h m'
132
143
case attempt of
133
144
Nothing -> processApplyAux hs p' s' m'
134
145
Just act -> return act
135
146
136
- drainOrTimeout :: s
137
- -> Delay
138
- -> Queue
139
- -> [DispatchPriority s ]
140
- -> TimeoutHandler s
141
- -> Process (ProcessAction s , Delay , Queue )
142
147
drainOrTimeout pState delay queue ps' h = do
143
148
let matches = [ matchMessage return ]
144
149
recv = case delay of
0 commit comments