1use crate::common::child_spec::ChildSpec;
2mod sup_actor;
3mod sup_context;
4
5pub use sup_actor::uniform_sup;
6pub use sup_context::UniformSupContext;
7
8pub mod child_type {
9 use mm1_common::types::AnyError;
10 use tokio::time::Instant;
11
12 use crate::common::factory::ActorFactory;
13 use crate::common::restart_intensity::{RestartIntensity, RestartStats};
14
15 pub trait UniformChildType<A> {
16 type Data;
17
18 fn new_data(&self, args: A) -> Self::Data;
19 fn make_runnable<F>(
20 &self,
21 factory: &F,
22 data: &mut Self::Data,
23 ) -> Result<F::Runnable, AnyError>
24 where
25 F: ActorFactory<Args = A>;
26 fn should_restart(
27 &self,
28 data: &mut Self::Data,
29 normal_exit: bool,
30 ) -> Result<bool, AnyError>;
31 }
32
33 #[derive(Debug, Clone, Copy)]
34 pub struct Temporary;
35
36 pub type Permanent = Restarting<true>;
37
38 pub type Transient = Restarting<false>;
39
40 impl<A> UniformChildType<A> for Temporary {
41 type Data = Option<A>;
42
43 fn new_data(&self, args: A) -> Self::Data {
44 Some(args)
45 }
46
47 fn make_runnable<F>(
48 &self,
49 factory: &F,
50 data: &mut Self::Data,
51 ) -> Result<F::Runnable, AnyError>
52 where
53 F: ActorFactory<Args = A>,
54 {
55 let args = data.take().ok_or_else(|| eyre::format_err!("args gone"))?;
56 let runnable = factory.produce(args);
57 Ok(runnable)
58 }
59
60 fn should_restart(
61 &self,
62 _data: &mut Self::Data,
63 _normal_exit: bool,
64 ) -> Result<bool, AnyError> {
65 Ok(false)
66 }
67 }
68
69 #[doc(hidden)]
70 pub struct Restarting<const RESTART_ON_NORMAL_EXIT: bool> {
71 restart_intensity: RestartIntensity,
72 }
73
74 impl<const RESTART_ON_NORMAL_EXIT: bool, A> UniformChildType<A>
75 for Restarting<RESTART_ON_NORMAL_EXIT>
76 where
77 A: Clone,
78 {
79 type Data = ChildData<A>;
80
81 fn new_data(&self, args: A) -> Self::Data {
82 let restarts = self.restart_intensity.new_stats();
83 ChildData { args, restarts }
84 }
85
86 fn make_runnable<F>(
87 &self,
88 factory: &F,
89 data: &mut Self::Data,
90 ) -> Result<F::Runnable, AnyError>
91 where
92 F: ActorFactory<Args = A>,
93 {
94 let args = data.args.clone();
95 let runnable = factory.produce(args);
96 Ok(runnable)
97 }
98
99 fn should_restart(
100 &self,
101 data: &mut Self::Data,
102 _normal_exit: bool,
103 ) -> Result<bool, AnyError> {
104 self.restart_intensity
105 .report_exit(&mut data.restarts, Instant::now())?;
106 Ok(RESTART_ON_NORMAL_EXIT)
107 }
108 }
109
110 #[doc(hidden)]
111 pub struct ChildData<A> {
112 args: A,
113 restarts: RestartStats,
114 }
115}
116
117pub struct UniformSup<F, C> {
118 pub child_spec: ChildSpec<F, C>,
119}
120
121impl<F, C> UniformSup<F, C> {
122 pub fn new(child_spec: ChildSpec<F, C>) -> Self {
123 Self { child_spec }
124 }
125}
126
127impl<F, C> Clone for UniformSup<F, C>
128where
129 ChildSpec<F, C>: Clone,
130{
131 fn clone(&self) -> Self {
132 Self {
133 child_spec: self.child_spec.clone(),
134 }
135 }
136}