1use serde::{Deserialize, Serialize};
4use std::collections::VecDeque;
5use std::time::{Duration, Instant};
6
7use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
8
9#[derive(
11 Debug,
12 Default,
13 Clone,
14 Copy,
15 PartialEq,
16 Eq,
17 Serialize,
18 Deserialize,
19 Archive,
20 RkyvSerialize,
21 RkyvDeserialize,
22)]
23#[rkyv(derive(Debug))]
24pub enum RestartStrategy {
25 #[default]
27 OneForOne,
28 OneForAll,
30 RestForOne,
32}
33
34#[derive(
36 Debug,
37 Default,
38 Clone,
39 Copy,
40 PartialEq,
41 Eq,
42 Serialize,
43 Deserialize,
44 Archive,
45 RkyvSerialize,
46 RkyvDeserialize,
47)]
48#[rkyv(derive(Debug))]
49pub enum RestartPolicy {
50 #[default]
52 Permanent,
53 Temporary,
55 Transient,
57}
58
59#[derive(Debug, Clone, Copy)]
61pub struct RestartIntensity {
62 pub max_restarts: usize,
64 pub within_seconds: u64,
66}
67
68impl RestartIntensity {
69 #[inline]
79 pub const fn new(max_restarts: usize, within_seconds: u64) -> Self {
80 Self {
81 max_restarts,
82 within_seconds,
83 }
84 }
85}
86
87impl Default for RestartIntensity {
88 fn default() -> Self {
89 Self::new(3, 5)
90 }
91}
92
93#[derive(Debug)]
95pub(crate) struct RestartTracker {
96 intensity: RestartIntensity,
97 restart_times: VecDeque<Instant>,
98}
99
100impl RestartTracker {
101 pub(crate) fn new(intensity: RestartIntensity) -> Self {
102 Self {
103 intensity,
104 restart_times: VecDeque::with_capacity(intensity.max_restarts + 1),
106 }
107 }
108
109 pub(crate) fn record_restart(&mut self) -> bool {
111 let now = Instant::now();
112 let cutoff = now - Duration::from_secs(self.intensity.within_seconds);
113
114 while let Some(&time) = self.restart_times.front() {
116 if time < cutoff {
117 self.restart_times.pop_front();
118 } else {
119 break;
120 }
121 }
122
123 self.restart_times.push_back(now);
124
125 self.restart_times.len() > self.intensity.max_restarts
127 }
128
129 #[allow(dead_code)]
130 pub(crate) fn reset(&mut self) {
131 self.restart_times.clear();
132 }
133}