behavior_actors/atomic/worker/
initialization.rs1use std::sync::Arc;
4
5use core::marker::PhantomData;
6
7use behavior::{
8 ActionItem, Behavior, BehaviorAddr, EndpointAddress, EstablishedRecipient, Here,
9 InterpretationProgress, InterpreterRequest, ItemSettlement, Never, ReturnsToEmitter,
10 finish_item, prepare_item,
11};
12
13use crate::ChildStopped;
14
15use super::WorkerAttempt;
16
17#[derive(Clone)]
19pub struct InitializationAttempt {
20 worker: WorkerAttempt,
21 token: Arc<()>,
22}
23
24impl InitializationAttempt {
25 pub(in crate::atomic) fn issued(worker: &WorkerAttempt) -> Self {
26 Self {
27 worker: worker.clone(),
28 token: Arc::new(()),
29 }
30 }
31}
32
33impl core::fmt::Debug for InitializationAttempt {
34 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
35 formatter
36 .debug_tuple("InitializationAttempt")
37 .field(&self.worker)
38 .finish()
39 }
40}
41
42impl PartialEq for InitializationAttempt {
43 fn eq(&self, other: &Self) -> bool {
44 self.worker == other.worker && Arc::ptr_eq(&self.token, &other.token)
45 }
46}
47
48impl Eq for InitializationAttempt {}
49
50#[must_use = "activation authority must be consumed or retained"]
73pub struct ActivationPermit<W>
74where
75 W: Behavior,
76 BehaviorAddr<W>: EndpointAddress,
77{
78 worker: WorkerAttempt,
79 initialization: InitializationAttempt,
80 target: EstablishedRecipient<W::Protocol>,
81 worker_type: PhantomData<fn() -> W>,
82}
83
84impl<W> ActivationPermit<W>
85where
86 W: Behavior,
87 BehaviorAddr<W>: EndpointAddress,
88{
89 #[must_use]
91 pub fn worker(&self) -> WorkerAttempt {
92 self.worker.clone()
93 }
94
95 #[must_use]
97 pub fn initialization(&self) -> InitializationAttempt {
98 self.initialization.clone()
99 }
100
101 #[must_use]
103 pub fn target(&self) -> EstablishedRecipient<W::Protocol> {
104 self.target.clone()
105 }
106
107 pub(in super::super) fn worker_evidence(&self) -> &WorkerAttempt {
108 &self.worker
109 }
110}
111
112#[must_use = "worker initialization custody must settle or transfer outward"]
125pub struct InitializeWorker<W, P>
126where
127 W: Behavior,
128 BehaviorAddr<W>: EndpointAddress,
129{
130 worker: WorkerAttempt,
131 initialization: InitializationAttempt,
132 target: EstablishedRecipient<W::Protocol>,
133 activation: P,
134}
135
136impl<W, P> InitializeWorker<W, P>
137where
138 W: Behavior,
139 BehaviorAddr<W>: EndpointAddress,
140{
141 pub(in crate::atomic) fn new(
142 worker: WorkerAttempt,
143 initialization: InitializationAttempt,
144 target: EstablishedRecipient<W::Protocol>,
145 activation: P,
146 ) -> Self {
147 Self {
148 worker,
149 initialization,
150 target,
151 activation,
152 }
153 }
154
155 #[must_use]
157 pub fn target(&self) -> EstablishedRecipient<W::Protocol> {
158 self.target.clone()
159 }
160
161 #[must_use]
163 pub fn worker(&self) -> WorkerAttempt {
164 self.worker.clone()
165 }
166
167 #[must_use]
169 pub fn initialization(&self) -> InitializationAttempt {
170 self.initialization.clone()
171 }
172
173 #[must_use]
175 pub fn resolve(
176 self,
177 result: WorkerInitializationOutcome<W>,
178 ) -> WorkerInitializationReport<W, P> {
179 let Self {
180 worker,
181 initialization,
182 target,
183 activation,
184 } = self;
185 match result {
186 WorkerInitializationOutcome::ReadyForActivation => {
187 WorkerInitializationReport::ReadyForActivation {
188 worker: worker.clone(),
189 initialization: initialization.clone(),
190 activation,
191 permit: ActivationPermit {
192 worker,
193 initialization,
194 target,
195 worker_type: PhantomData,
196 },
197 }
198 }
199 WorkerInitializationOutcome::EffectsRejected(failure) => {
200 WorkerInitializationReport::EffectsRejected {
201 worker,
202 initialization,
203 activation,
204 failure,
205 }
206 }
207 WorkerInitializationOutcome::Stopped(stopped) => WorkerInitializationReport::Stopped {
208 worker,
209 initialization,
210 activation,
211 stopped,
212 },
213 }
214 }
215}
216
217impl<W, P> InterpreterRequest for InitializeWorker<W, P>
218where
219 W: Behavior,
220 BehaviorAddr<W>: EndpointAddress,
221{
222 type ReturnToEmitter = ReturnsToEmitter<WorkerInitializationReport<W, P>, Here>;
223 type LogicalProtocols = behavior::NoBirthProtocols;
224}
225
226impl<W, P> ActionItem for InitializeWorker<W, P>
227where
228 W: Behavior,
229 BehaviorAddr<W>: EndpointAddress,
230 EstablishedRecipient<W::Protocol>: Send,
231 P: Send,
232{
233 type Custody = (Option<Self>, Option<Self::Reply>);
234 type Input<'a>
235 = &'a mut Option<Self>
236 where
237 Self: 'a;
238 type Reply = ItemSettlement<Self, Self::Accepted, Self::Rejection, Self::Prerequisite>;
239
240 fn prepare_interpretation(
241 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
242 ) {
243 prepare_item::<Self>(progress);
244 }
245
246 fn interpretation_input<'a>(
247 custody: &'a mut Self::Custody,
248 ) -> Option<(Self::Input<'a>, &'a mut Option<Self::Reply>)>
249 where
250 Self: 'a,
251 {
252 match custody {
253 (input @ Some(_), received @ None) => Some((input, received)),
254 _ => None,
255 }
256 }
257
258 fn finish_interpretation(
259 progress: &mut Option<InterpretationProgress<Self, Self::Custody, Self::Reply>>,
260 ) {
261 finish_item::<Self>(progress);
262 }
263
264 type Accepted = ();
265 type Rejection = Never;
266 type Prerequisite = Never;
267}
268
269pub enum WorkerInitializationOutcome<W>
271where
272 W: Behavior,
273{
274 ReadyForActivation,
275 EffectsRejected(WorkerInitializationFailure),
276 Stopped(ChildStopped<BehaviorAddr<W>>),
277}
278
279pub enum WorkerInitializationReport<W, P>
281where
282 W: Behavior,
283 BehaviorAddr<W>: EndpointAddress,
284{
285 ReadyForActivation {
286 worker: WorkerAttempt,
287 initialization: InitializationAttempt,
288 activation: P,
289 permit: ActivationPermit<W>,
290 },
291 EffectsRejected {
292 worker: WorkerAttempt,
293 initialization: InitializationAttempt,
294 activation: P,
295 failure: WorkerInitializationFailure,
296 },
297 Stopped {
298 worker: WorkerAttempt,
299 initialization: InitializationAttempt,
300 activation: P,
301 stopped: ChildStopped<BehaviorAddr<W>>,
302 },
303}
304
305impl<W, P> WorkerInitializationReport<W, P>
306where
307 W: Behavior,
308 BehaviorAddr<W>: EndpointAddress,
309{
310 pub(in crate::atomic) fn worker(&self) -> &WorkerAttempt {
311 match self {
312 Self::ReadyForActivation { worker, .. }
313 | Self::EffectsRejected { worker, .. }
314 | Self::Stopped { worker, .. } => worker,
315 }
316 }
317
318 pub(in crate::atomic) fn initialization(&self) -> &InitializationAttempt {
319 match self {
320 Self::ReadyForActivation { initialization, .. }
321 | Self::EffectsRejected { initialization, .. }
322 | Self::Stopped { initialization, .. } => initialization,
323 }
324 }
325}
326
327#[derive(Clone, Copy, Debug, Eq, PartialEq)]
330pub enum WorkerInitializationFailure {
331 EffectsRejected,
333 InterpreterCorrupt,
335}