35
35
-- The supervisors children are defined as a list of child specifications
36
36
-- (see 'ChildSpec'). When a supervisor is started, its children are started
37
37
-- in left-to-right (insertion order) according to this list. When a supervisor
38
- -- stops (or exits for any reason), it will terminate its children in reverse
38
+ -- stops (or exits for any reason), it will stop its children in reverse
39
39
-- (i.e., from right-to-left of insertion) order. Child specs can be added to
40
40
-- the supervisor after it has started, either on the left or right of the
41
41
-- existing list of children.
42
42
--
43
43
-- When the supervisor spawns its child processes, they are always linked to
44
44
-- their parent (i.e., the supervisor), therefore even if the supervisor is
45
- -- terminated abruptly by an asynchronous exception, the children will still be
45
+ -- killed abruptly by an asynchronous exception, the children will still be
46
46
-- taken down with it, though somewhat less ceremoniously in that case.
47
47
--
48
48
-- [Restart Strategies]
52
52
-- (see below for the rules governing child restart eligibility). Each restart
53
53
-- strategy comprises a 'RestartMode' and 'RestartLimit', which govern how
54
54
-- the restart should be handled, and the point at which the supervisor
55
- -- should give up and terminate itself respectively.
55
+ -- should give up and stop itself respectively.
56
56
--
57
57
-- With the exception of the @RestartOne@ strategy, which indicates that the
58
58
-- supervisor will restart /only/ the one individual failing child, each
141
141
-- restarts. In order prevent this, each restart strategy is parameterised
142
142
-- with a 'RestartLimit' that caps the number of restarts allowed within a
143
143
-- specific time period. If the supervisor exceeds this limit, it will stop,
144
- -- terminating all its children (in left-to-right order) and exit with the
144
+ -- stopping all its children (in left-to-right order) and exit with the
145
145
-- reason @ExitOther "ReachedMaxRestartIntensity"@.
146
146
--
147
147
-- The 'MaxRestarts' type is a positive integer, and together with a specified
152
152
-- as a single restart attempt, since otherwise it would likely exceed its
153
153
-- maximum restart intensity too quickly.
154
154
--
155
- -- [Child Restart and Termination Policies]
155
+ -- [Child Restart and Stop Policies]
156
156
--
157
157
-- When the supervisor detects that a child has died, the 'RestartPolicy'
158
158
-- configured in the child specification is used to determin what to do. If
159
159
-- the this is set to @Permanent@, then the child is always restarted.
160
160
-- If it is @Temporary@, then the child is never restarted and the child
161
161
-- specification is removed from the supervisor. A @Transient@ child will
162
- -- be restarted only if it terminates /abnormally/, otherwise it is left
162
+ -- be restarted only if it exits /abnormally/, otherwise it is left
163
163
-- inactive (but its specification is left in place). Finally, an @Intrinsic@
164
164
-- child is treated like a @Transient@ one, except that if /this/ kind of child
165
165
-- exits /normally/, then the supervisor will also exit normally.
166
166
--
167
- -- When the supervisor does terminate a child, the 'ChildTerminationPolicy'
167
+ -- When the supervisor does stop a child process , the "ChildStopPolicy"
168
168
-- provided with the 'ChildSpec' determines how the supervisor should go
169
- -- about doing so. If this is @TerminateImmediately@ , then the child will
169
+ -- about doing so. If this is "StopImmediately" , then the child will
170
170
-- be killed without further notice, which means the child will /not/ have
171
171
-- an opportunity to clean up any internal state and/or release any held
172
- -- resources. If the policy is @TerminateTimeout delay@ however, the child
172
+ -- resources. If the policy is @StopTimeout delay@ however, the child
173
173
-- will be sent an /exit signal/ instead, i.e., the supervisor will cause
174
174
-- the child to exit via @exit childPid ExitShutdown@, and then will wait
175
175
-- until the given @delay@ for the child to exit normally. If this does not
176
176
-- happen within the given delay, the supervisor will revert to the more
177
- -- aggressive @TerminateImmediately@ policy and try again. Any errors that
177
+ -- aggressive "StopImmediately" policy and try again. Any errors that
178
178
-- occur during a timed-out shutdown will be logged, however exit reasons
179
- -- resulting from @TerminateImmediately@ are ignored.
179
+ -- resulting from "StopImmediately" are ignored.
180
180
--
181
181
-- [Creating Child Specs]
182
182
--
195
195
-- who've manually registered with the /remote table/ and don't with to use
196
196
-- tempate haskell (e.g. users of the Explicit closures API).
197
197
--
198
- -- [Supervision Trees & Supervisor Termination ]
198
+ -- [Supervision Trees & Supervisor Shutdown ]
199
199
--
200
200
-- To create a supervision tree, one simply adds supervisors below one another
201
201
-- as children, setting the @childType@ field of their 'ChildSpec' to
@@ -211,7 +211,7 @@ module Control.Distributed.Process.Supervisor
211
211
ChildSpec (.. )
212
212
, ChildKey
213
213
, ChildType (.. )
214
- , ChildTerminationPolicy (.. )
214
+ , ChildStopPolicy (.. )
215
215
, ChildStart (.. )
216
216
, RegisteredName (LocalName , CustomRegister )
217
217
, RestartPolicy (.. )
@@ -246,8 +246,8 @@ module Control.Distributed.Process.Supervisor
246
246
, StartChildResult (.. )
247
247
, startChild
248
248
, startNewChild
249
- , terminateChild
250
- , TerminateChildResult (.. )
249
+ , stopChild
250
+ , StopChildResult (.. )
251
251
, deleteChild
252
252
, DeleteChildResult (.. )
253
253
, restartChild
@@ -342,9 +342,7 @@ import Control.Distributed.Process.ManagedProcess.Server.Priority
342
342
, prioritiseCall_
343
343
, prioritiseInfo_
344
344
, setPriority
345
- , runAfter
346
- , act
347
- , setProcessState
345
+ , evalAfter
348
346
)
349
347
import Control.Distributed.Process.ManagedProcess.Server.Restricted
350
348
( RestrictedProcess
@@ -481,10 +479,10 @@ data DelayedRestart = DelayedRestart !ChildKey !DiedReason
481
479
instance Binary DelayedRestart where
482
480
instance NFData DelayedRestart
483
481
484
- data TerminateChildReq = TerminateChildReq ! ChildKey
482
+ data StopChildReq = StopChildReq ! ChildKey
485
483
deriving (Typeable , Generic , Show , Eq )
486
- instance Binary TerminateChildReq where
487
- instance NFData TerminateChildReq where
484
+ instance Binary StopChildReq where
485
+ instance NFData StopChildReq where
488
486
489
487
data IgnoreChildReq = IgnoreChildReq ! ChildPid
490
488
deriving (Typeable , Generic )
@@ -574,18 +572,18 @@ startNewChild :: Addressable a
574
572
startNewChild addr spec = Unsafe. call addr $ AddChild True spec
575
573
576
574
-- | Delete a supervised child. The child must already be stopped (see
577
- -- 'terminateChild ').
575
+ -- 'stopChild ').
578
576
--
579
577
deleteChild :: Addressable a => a -> ChildKey -> Process DeleteChildResult
580
578
deleteChild sid childKey = Unsafe. call sid $ DeleteChild childKey
581
579
582
- -- | Terminate a running child.
580
+ -- | Stop a running child.
583
581
--
584
- terminateChild :: Addressable a
582
+ stopChild :: Addressable a
585
583
=> a
586
584
-> ChildKey
587
- -> Process TerminateChildResult
588
- terminateChild sid = Unsafe. call sid . TerminateChildReq
585
+ -> Process StopChildResult
586
+ stopChild sid = Unsafe. call sid . StopChildReq
589
587
590
588
-- | Forcibly restart a running child.
591
589
--
@@ -595,7 +593,7 @@ restartChild :: Addressable a
595
593
-> Process RestartChildResult
596
594
restartChild sid = Unsafe. call sid . RestartChildReq
597
595
598
- -- | Gracefully terminate a running supervisor. Returns immediately if the
596
+ -- | Gracefully stop/shutdown a running supervisor. Returns immediately if the
599
597
-- /address/ cannot be resolved.
600
598
--
601
599
shutdown :: Resolvable a => a -> Process ()
@@ -720,7 +718,7 @@ processDefinition =
720
718
apiHandlers = [
721
719
Restricted. handleCast handleIgnore
722
720
-- adding, removing and (optionally) starting new child specs
723
- , handleCall handleTerminateChild
721
+ , handleCall handleStopChild
724
722
, Restricted. handleCall handleDeleteChild
725
723
, Restricted. handleCallIf (input (\ (AddChild immediate _) -> not immediate))
726
724
handleAddChild
@@ -867,7 +865,7 @@ handleDelayedRestart state (DelayedRestart key reason) =
867
865
let child = findChild key state in do
868
866
case child of
869
867
Nothing ->
870
- continue state -- a child could've been terminated and removed by now
868
+ continue state -- a child could've been stopped and removed by now
871
869
Just ((ChildRestarting childPid), spec) -> do
872
870
-- TODO: we ignore the unnecessary .active re-assignments in
873
871
-- tryRestartChild, in order to keep the code simple - it would be good to
@@ -876,18 +874,18 @@ handleDelayedRestart state (DelayedRestart key reason) =
876
874
Just other -> do
877
875
die $ ExitOther $ (supErrId " .handleDelayedRestart:InvalidState: " ) ++ (show other)
878
876
879
- handleTerminateChild :: State
880
- -> TerminateChildReq
881
- -> Process (ProcessReply TerminateChildResult State )
882
- handleTerminateChild state (TerminateChildReq key) =
877
+ handleStopChild :: State
878
+ -> StopChildReq
879
+ -> Process (ProcessReply StopChildResult State )
880
+ handleStopChild state (StopChildReq key) =
883
881
let child = findChild key state in
884
882
case child of
885
883
Nothing ->
886
- reply TerminateChildUnknownId state
884
+ reply StopChildUnknownId state
887
885
Just (ChildStopped , _) ->
888
- reply TerminateChildOk state
886
+ reply StopChildOk state
889
887
Just (ref, spec) ->
890
- reply TerminateChildOk =<< doTerminateChild ref spec state
888
+ reply StopChildOk =<< doStopChild ref spec state
891
889
892
890
handleGetStats :: StatsReq
893
891
-> RestrictedProcess State (Result SupervisorStats )
@@ -916,8 +914,8 @@ handleMonitorSignal state (ProcessMonitorNotification _ childPid reason) = do
916
914
--------------------------------------------------------------------------------
917
915
918
916
handleShutdown :: ExitState State -> ExitReason -> Process ()
919
- handleShutdown state r@ (ExitOther reason) = terminateChildren (exitState state) r >> die reason
920
- handleShutdown state r = terminateChildren (exitState state) r
917
+ handleShutdown state r@ (ExitOther reason) = stopChildren (exitState state) r >> die reason
918
+ handleShutdown state r = stopChildren (exitState state) r
921
919
922
920
--------------------------------------------------------------------------------
923
921
-- Child Start/Restart Handling --
@@ -1003,14 +1001,14 @@ tryRestartBranch rs sp dr st = -- TODO: use DiedReason for logging...
1003
1001
us <- getSelfPid
1004
1002
cPid <- resolve cr
1005
1003
report $ SupervisedChildRestarting us cPid (childKey cs) (ExitOther " RestartedBySupervisor" )
1006
- doTerminateChild cr cs s >>= (flip startIt) ch
1004
+ doStopChild cr cs s >>= (flip startIt) ch
1007
1005
1008
1006
stopIt :: State -> Child -> Process State
1009
1007
stopIt s (cr, cs) = do
1010
1008
us <- getSelfPid
1011
1009
cPid <- resolve cr
1012
1010
report $ SupervisedChildRestarting us cPid (childKey cs) (ExitOther " RestartedBySupervisor" )
1013
- doTerminateChild cr cs s
1011
+ doStopChild cr cs s
1014
1012
1015
1013
startIt :: State -> Child -> Process State
1016
1014
startIt s (_, cs)
@@ -1077,25 +1075,25 @@ tryRestartBranch rs sp dr st = -- TODO: use DiedReason for logging...
1077
1075
LeftToRight -> tree
1078
1076
RightToLeft -> Seq.reverse tree
1079
1077
1080
- -- TODO: THIS IS INCORRECT... currently (below), we terminate
1078
+ -- TODO: THIS IS INCORRECT... currently (below), we stop
1081
1079
-- the branch in parallel, but wait on all the exits and then
1082
1080
-- restart sequentially (based on 'order'). That's not what the
1083
1081
-- 'RestartParallel' mode advertised, but more importantly, it's
1084
1082
-- not clear what the semantics for error handling (viz restart errors)
1085
1083
-- should actually be.
1086
1084
1087
- asyncs <- forM (toList tree') $ \ch -> async $ asyncTerminate ch
1085
+ asyncs <- forM (toList tree') $ \ch -> async $ asyncStop ch
1088
1086
(_errs, st') <- foldlM collectExits ([], activeState) asyncs
1089
1087
-- TODO: report errs
1090
1088
apply $ foldlM startIt st' tree'
1091
1089
where
1092
- asyncTerminate :: Child -> Process (Maybe (ChildKey, ChildPid))
1093
- asyncTerminate (cr, cs) = do
1090
+ asyncStop :: Child -> Process (Maybe (ChildKey, ChildPid))
1091
+ asyncStop (cr, cs) = do
1094
1092
mPid <- resolve cr
1095
1093
case mPid of
1096
1094
Nothing -> return Nothing
1097
1095
Just childPid -> do
1098
- void $ doTerminateChild cr cs activeState
1096
+ void $ doStopChild cr cs activeState
1099
1097
return $ Just (childKey cs, childPid)
1100
1098
1101
1099
collectExits :: ([ExitReason], State)
@@ -1190,13 +1188,13 @@ doRestartDelay :: ChildPid
1190
1188
-> State
1191
1189
-> Process (ProcessAction State )
1192
1190
doRestartDelay oldPid rDelay spec reason state = do
1193
- act $ do
1194
- void $ runAfter rDelay $ DelayedRestart (childKey spec) reason
1195
- setProcessState $ ( (active ^: Map. filter (/= chKey))
1196
- . (bumpStats Active chType decrement)
1197
- . (restarts ^= [] )
1198
- $ maybe state id (updateChild chKey (setChildRestarting oldPid) state)
1199
- )
1191
+ evalAfter rDelay
1192
+ ( DelayedRestart (childKey spec) reason)
1193
+ $ ( (active ^: Map. filter (/= chKey))
1194
+ . (bumpStats Active chType decrement)
1195
+ . (restarts ^= [] )
1196
+ $ maybe state id (updateChild chKey (setChildRestarting oldPid) state)
1197
+ )
1200
1198
where
1201
1199
chKey = childKey spec
1202
1200
chType = childType spec
@@ -1335,39 +1333,39 @@ filterInitFailures sup childPid ex = do
1335
1333
ChildInitIgnore -> Unsafe. cast sup $ IgnoreChildReq childPid
1336
1334
1337
1335
--------------------------------------------------------------------------------
1338
- -- Child Termination /Shutdown --
1336
+ -- Child Stop /Shutdown --
1339
1337
--------------------------------------------------------------------------------
1340
1338
1341
- terminateChildren :: State -> ExitReason -> Process ()
1342
- terminateChildren state er = do
1339
+ stopChildren :: State -> ExitReason -> Process ()
1340
+ stopChildren state er = do
1343
1341
us <- getSelfPid
1344
1342
let strat = shutdownStrategy state
1345
1343
report $ SupervisorShutdown us strat er
1346
1344
case strat of
1347
1345
ParallelShutdown -> do
1348
1346
let allChildren = toList $ state ^. specs
1349
1347
terminatorPids <- forM allChildren $ \ ch -> do
1350
- pid <- spawnLocal $ void $ syncTerminate ch $ (active ^= Map. empty) state
1348
+ pid <- spawnLocal $ void $ syncStop ch $ (active ^= Map. empty) state
1351
1349
mRef <- monitor pid
1352
1350
return (mRef, pid)
1353
1351
terminationErrors <- collectExits [] $ zip terminatorPids (map snd allChildren)
1354
- -- it seems these would also be logged individually in doTerminateChild
1352
+ -- it seems these would also be logged individually in doStopChild
1355
1353
case terminationErrors of
1356
1354
[] -> return ()
1357
1355
_ -> do
1358
1356
sup <- getSelfPid
1359
1357
void $ logEntry Log. error $
1360
- mkReport " Errors in terminateChildren / ParallelShutdown"
1358
+ mkReport " Errors in stopChildren / ParallelShutdown"
1361
1359
sup " n/a" (show terminationErrors)
1362
1360
SequentialShutdown ord -> do
1363
1361
let specs' = state ^. specs
1364
1362
let allChildren = case ord of
1365
1363
RightToLeft -> Seq. reverse specs'
1366
1364
LeftToRight -> specs'
1367
- void $ foldlM (flip syncTerminate ) state (toList allChildren)
1365
+ void $ foldlM (flip syncStop ) state (toList allChildren)
1368
1366
where
1369
- syncTerminate :: Child -> State -> Process State
1370
- syncTerminate (cr, cs) state' = doTerminateChild cr cs state'
1367
+ syncStop :: Child -> State -> Process State
1368
+ syncStop (cr, cs) state' = doStopChild cr cs state'
1371
1369
1372
1370
collectExits :: [(ProcessId , DiedReason )]
1373
1371
-> [((MonitorRef , ProcessId ), ChildSpec )]
@@ -1385,13 +1383,13 @@ terminateChildren state er = do
1385
1383
(DiedNormal , _) -> collectExits errors remaining
1386
1384
(_, Nothing ) -> collectExits errors remaining
1387
1385
(DiedException _, Just sp') -> do
1388
- if (childStop sp') == TerminateImmediately
1386
+ if (childStop sp') == StopImmediately
1389
1387
then collectExits errors remaining
1390
1388
else collectExits ((pid, reason): errors) remaining
1391
1389
_ -> collectExits ((pid, reason): errors) remaining
1392
1390
1393
- doTerminateChild :: ChildRef -> ChildSpec -> State -> Process State
1394
- doTerminateChild ref spec state = do
1391
+ doStopChild :: ChildRef -> ChildSpec -> State -> Process State
1392
+ doStopChild ref spec state = do
1395
1393
us <- getSelfPid
1396
1394
mPid <- resolve ref
1397
1395
case mPid of
@@ -1412,16 +1410,16 @@ doTerminateChild ref spec state = do
1412
1410
chKey = childKey spec
1413
1411
updateStopped = maybe state id $ updateChild chKey (setChildStopped False ) state
1414
1412
1415
- childShutdown :: ChildTerminationPolicy
1413
+ childShutdown :: ChildStopPolicy
1416
1414
-> ChildPid
1417
1415
-> State
1418
1416
-> Process DiedReason
1419
1417
childShutdown policy childPid st = mask $ \ restore -> do
1420
1418
case policy of
1421
- (TerminateTimeout t) -> exit childPid ExitShutdown >> await restore childPid t st
1419
+ (StopTimeout t) -> exit childPid ExitShutdown >> await restore childPid t st
1422
1420
-- we ignore DiedReason for brutal kills
1423
- TerminateImmediately -> do
1424
- kill childPid " TerminatedBySupervisor "
1421
+ StopImmediately -> do
1422
+ kill childPid " StoppedBySupervisor "
1425
1423
void $ await restore childPid Infinity st
1426
1424
return DiedNormal
1427
1425
where
@@ -1436,7 +1434,7 @@ childShutdown policy childPid st = mask $ \restore -> do
1436
1434
Delay t -> receiveTimeout (asTimeout t) (matches mRef)
1437
1435
-- let recv' = if monitored then recv else withMonitor childPid' recv
1438
1436
res <- recv `finally` (unmonitor mRef)
1439
- restore' $ maybe (childShutdown TerminateImmediately childPid' state) return res
1437
+ restore' $ maybe (childShutdown StopImmediately childPid' state) return res
1440
1438
1441
1439
matches :: MonitorRef -> [Match DiedReason ]
1442
1440
matches m = [
0 commit comments