running_process/broker/server/
spawn_wait.rs1use std::time::Duration;
8
9pub const DEFAULT_SPAWN_WAIT_HARD_CEILING: Duration = Duration::from_secs(60);
11
12pub const SPAWN_WAIT_BACKOFF_SEQUENCE: [Duration; 6] = [
14 Duration::from_millis(50),
15 Duration::from_millis(100),
16 Duration::from_millis(200),
17 Duration::from_millis(500),
18 Duration::from_secs(1),
19 Duration::from_secs(2),
20];
21
22#[derive(Clone, Copy, Debug, PartialEq, Eq)]
24pub struct SpawnWaitPolicy {
25 hard_ceiling: Duration,
26}
27
28impl SpawnWaitPolicy {
29 pub fn new() -> Self {
31 Self::with_hard_ceiling(DEFAULT_SPAWN_WAIT_HARD_CEILING)
32 }
33
34 pub fn with_hard_ceiling(hard_ceiling: Duration) -> Self {
36 Self { hard_ceiling }
37 }
38
39 pub fn hard_ceiling(&self) -> Duration {
41 self.hard_ceiling
42 }
43
44 pub fn backoff_for_attempt(&self, attempt: usize) -> Duration {
49 let capped_index = attempt.min(SPAWN_WAIT_BACKOFF_SEQUENCE.len() - 1);
50 SPAWN_WAIT_BACKOFF_SEQUENCE[capped_index]
51 }
52
53 pub fn decide(&self, probe: SpawnWaitProbe) -> SpawnWaitDecision {
55 if probe.endpoint_ready {
56 return SpawnWaitDecision::EndpointReady;
57 }
58
59 if !probe.daemon_alive {
60 return SpawnWaitDecision::DaemonExitedBeforeReady;
61 }
62
63 if probe.elapsed >= self.hard_ceiling {
64 return SpawnWaitDecision::Timeout {
65 hard_ceiling: self.hard_ceiling,
66 };
67 }
68
69 SpawnWaitDecision::Sleep {
70 duration: self
71 .backoff_for_attempt(probe.attempt)
72 .min(self.hard_ceiling - probe.elapsed),
73 }
74 }
75}
76
77impl Default for SpawnWaitPolicy {
78 fn default() -> Self {
79 Self::new()
80 }
81}
82
83#[derive(Clone, Copy, Debug, PartialEq, Eq)]
85pub struct SpawnWaitProbe {
86 pub elapsed: Duration,
88 pub daemon_alive: bool,
90 pub endpoint_ready: bool,
92 pub attempt: usize,
94}
95
96impl SpawnWaitProbe {
97 pub fn new(
99 elapsed: Duration,
100 daemon_alive: bool,
101 endpoint_ready: bool,
102 attempt: usize,
103 ) -> Self {
104 Self {
105 elapsed,
106 daemon_alive,
107 endpoint_ready,
108 attempt,
109 }
110 }
111}
112
113#[derive(Clone, Copy, Debug, PartialEq, Eq)]
115pub enum SpawnWaitDecision {
116 EndpointReady,
118 DaemonExitedBeforeReady,
120 Timeout {
122 hard_ceiling: Duration,
124 },
125 Sleep {
127 duration: Duration,
129 },
130}