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(
37                "stable_addr_refresher",
38                &self.stable_addr_refresher.is_some(),
39            )
40            .finish()
41    }
42}
43
44impl<R: crate::bridge::Reactor> ChildSpec<R> {
45    pub fn new(
46        name: impl Into<String>,
47        restart: RestartPolicy,
48        shutdown: ShutdownPolicy,
49        namespace: NamespacePolicy,
50        factory: impl Fn() -> Box<dyn Actor<R>> + Send + Sync + 'static,
51    ) -> Self {
52        Self {
53            name: name.into(),
54            restart,
55            shutdown,
56            namespace,
57            mailbox_capacity: 1024, // Default capacity
58            factory: Arc::new(factory),
59            stable_addr_refresher: None,
60        }
61    }
62
63    /// Builder-style method to override the default mailbox capacity.
64    pub fn with_mailbox_capacity(mut self, capacity: usize) -> Self {
65        self.mailbox_capacity = capacity;
66        self
67    }
68
69    /// Attach an [`AddrRefresher`] so the supervisor updates a [`StableAddr`]
70    /// after each spawn of this child.
71    pub fn with_stable_addr(mut self, refresher: Arc<dyn AddrRefresher>) -> Self {
72        self.stable_addr_refresher = Some(refresher);
73        self
74    }
75}