Skip to main content

palladium_actor/
spec.rs

1use crate::actor::Actor;
2use crate::policy::{NamespacePolicy, RestartPolicy, ShutdownPolicy};
3use crate::stable::AddrRefresher;
4use std::fmt;
5use std::sync::Arc;
6
7/// Specification provided at spawn time that governs a child actor's lifecycle.
8///
9/// `factory` is called by the supervisor whenever it needs to (re)create the
10/// child actor — at initial spawn and after each restart.  It must be
11/// `Send + Sync` so the supervisor task can share the spec across threads.
12#[derive(Clone)]
13pub struct ChildSpec<R: crate::bridge::Reactor> {
14    pub name: String,
15    pub restart: RestartPolicy,
16    pub shutdown: ShutdownPolicy,
17    pub namespace: NamespacePolicy,
18    pub mailbox_capacity: usize,
19    /// Factory function that produces a fresh `Box<dyn Actor<R>>` on each
20    /// (re)spawn.  The closure must be cheap to call repeatedly.
21    pub factory: Arc<dyn Fn() -> Box<dyn Actor<R>> + Send + Sync>,
22    /// Optional refresher notified by the supervisor after each (re)spawn.
23    /// Set via [`ChildSpec::with_stable_addr`].
24    pub stable_addr_refresher: Option<Arc<dyn AddrRefresher>>,
25}
26
27impl<R: crate::bridge::Reactor> fmt::Debug for ChildSpec<R> {
28    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29        f.debug_struct("ChildSpec")
30            .field("name", &self.name)
31            .field("restart", &self.restart)
32            .field("shutdown", &self.shutdown)
33            .field("namespace", &self.namespace)
34            .field("mailbox_capacity", &self.mailbox_capacity)
35            .field("factory", &"<factory fn>")
36            .field("stable_addr_refresher", &self.stable_addr_refresher.is_some())
37            .finish()
38    }
39}
40
41impl<R: crate::bridge::Reactor> ChildSpec<R> {
42    pub fn new(
43        name: impl Into<String>,
44        restart: RestartPolicy,
45        shutdown: ShutdownPolicy,
46        namespace: NamespacePolicy,
47        factory: impl Fn() -> Box<dyn Actor<R>> + Send + Sync + 'static,
48    ) -> Self {
49        Self {
50            name: name.into(),
51            restart,
52            shutdown,
53            namespace,
54            mailbox_capacity: 1024, // Default capacity
55            factory: Arc::new(factory),
56            stable_addr_refresher: None,
57        }
58    }
59
60    /// Builder-style method to override the default mailbox capacity.
61    pub fn with_mailbox_capacity(mut self, capacity: usize) -> Self {
62        self.mailbox_capacity = capacity;
63        self
64    }
65
66    /// Attach an [`AddrRefresher`] so the supervisor updates a [`StableAddr`]
67    /// after each spawn of this child.
68    pub fn with_stable_addr(mut self, refresher: Arc<dyn AddrRefresher>) -> Self {
69        self.stable_addr_refresher = Some(refresher);
70        self
71    }
72}