agner_actors/
spawn_opts.rs

1use std::any::{Any, TypeId};
2use std::collections::{HashMap, HashSet};
3use std::sync::Arc;
4
5use crate::actor_id::ActorID;
6use crate::exit_handler::ExitHandler;
7
8const DEFAULT_MSG_INBOX_SIZE: usize = 1024;
9const DEFAULT_SIG_INBOX_SIZE: usize = 16;
10
11/// Options with which an actor will be spawned.
12///
13/// It is possible to specify:
14/// - the set of [actor-ids](crate::actor_id::ActorID) the newly spawned actor will be immediately
15///   linked to;
16/// - the sizes for msg-inbox and signal-inbox;
17/// - [exit-handler](crate::exit_handler::ExitHandler);
18/// - a "bag" of arbitrary properties (identified by their types).
19#[derive(Debug)]
20pub struct SpawnOpts {
21    links: HashSet<ActorID>,
22    msg_inbox_size: usize,
23    sig_inbox_size: usize,
24    exit_handler: Option<Arc<dyn ExitHandler>>,
25    data: HashMap<TypeId, Box<dyn Any + Send + Sync + 'static>>,
26}
27
28impl Default for SpawnOpts {
29    fn default() -> Self {
30        Self {
31            links: Default::default(),
32            msg_inbox_size: DEFAULT_MSG_INBOX_SIZE,
33            sig_inbox_size: DEFAULT_SIG_INBOX_SIZE,
34            exit_handler: None,
35            data: Default::default(),
36        }
37    }
38}
39
40impl SpawnOpts {
41    /// create new [SpawnOpts](SpawnOpts)
42    pub fn new() -> Self {
43        Default::default()
44    }
45}
46
47impl SpawnOpts {
48    /// add a linked actor
49    pub fn with_link(mut self, with: ActorID) -> Self {
50        self.links.insert(with);
51        self
52    }
53    /// iterator of linked actors
54    pub fn links(&self) -> impl Iterator<Item = ActorID> + '_ {
55        self.links.iter().copied()
56    }
57}
58
59impl SpawnOpts {
60    /// specify the capacity limit for msg-inbox
61    pub fn with_msg_inbox_size(mut self, sz: usize) -> Self {
62        self.msg_inbox_size = sz;
63        self
64    }
65
66    /// the capacity limit for msg-inbox
67    pub fn msg_inbox_size(&self) -> usize {
68        self.msg_inbox_size
69    }
70}
71
72impl SpawnOpts {
73    /// specify the capacity limit for signal-inbox
74    pub fn with_sig_inbox_size(mut self, sz: usize) -> Self {
75        self.sig_inbox_size = sz;
76        self
77    }
78
79    /// the capacity limit for signal-inbox
80    pub fn sig_inbox_size(&self) -> usize {
81        self.sig_inbox_size
82    }
83}
84
85impl SpawnOpts {
86    /// add arbitrary data into the [`Context`](crate::context::Context)
87    pub fn with_data<D>(mut self, data: D) -> Self
88    where
89        D: Any + Send + Sync + 'static,
90    {
91        let type_id = data.type_id();
92        let boxed = Box::new(data);
93        self.data.insert(type_id, boxed);
94        self
95    }
96
97    pub(crate) fn take_data(&mut self) -> HashMap<TypeId, Box<dyn Any + Send + Sync + 'static>> {
98        std::mem::take(&mut self.data)
99    }
100}
101
102impl SpawnOpts {
103    /// Specify the [exit-handler](crate::exit_handler::ExitHandler) for the spawned actor
104    pub fn with_exit_handler(mut self, exit_handler: Arc<dyn ExitHandler>) -> Self {
105        let _ = self.exit_handler.replace(exit_handler);
106        self
107    }
108    pub(crate) fn take_exit_handler(&mut self) -> Option<Arc<dyn ExitHandler>> {
109        self.exit_handler.take()
110    }
111}