agner_sup/common/
stop_child.rs1use std::time::Duration;
2
3use agner_actors::{ActorID, Exit, System};
4use agner_utils::future_timeout_ext::FutureTimeoutExt;
5
6const DEFAULT_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
7const DEFAULT_KILL_TIMEOUT: Duration = Duration::from_secs(5);
8
9#[derive(Debug, thiserror::Error)]
10#[error("Exit failed")]
11pub struct StopChildError;
12
13#[derive(Debug, Clone)]
14pub struct ShutdownSequence(Vec<(Exit, Duration)>);
15
16pub async fn stop_child(
18 system: System,
19 actor_id: ActorID,
20 shutdown_sequence: ShutdownSequence,
21) -> Result<Exit, StopChildError> {
22 for (exit, timeout) in shutdown_sequence.0.into_iter() {
23 system.exit(actor_id, exit).await;
24 if let Ok(actual_exit) = system.wait(actor_id).timeout(timeout).await {
25 return Ok(actual_exit)
26 }
27 }
28 Err(StopChildError)
29}
30
31impl Default for ShutdownSequence {
32 fn default() -> Self {
33 [(Exit::shutdown(), DEFAULT_SHUTDOWN_TIMEOUT), (Exit::kill(), DEFAULT_KILL_TIMEOUT)].into()
34 }
35}
36
37impl ShutdownSequence {
38 pub fn empty() -> Self {
39 Self(vec![])
40 }
41 pub fn add(mut self, exit: Exit, timeout: Duration) -> Self {
42 self.0.push((exit, timeout));
43 self
44 }
45}
46
47impl<I> From<I> for ShutdownSequence
48where
49 I: IntoIterator<Item = (Exit, Duration)>,
50{
51 fn from(seq: I) -> Self {
52 Self(seq.into_iter().collect())
53 }
54}