Skip to main content

nexus_acto_rs/actor/
actor_system.rs

1use std::sync::Arc;
2use std::time::Duration;
3
4use tokio::sync::Mutex;
5use uuid::Uuid;
6
7use crate::actor::actor::ExtendedPid;
8use crate::actor::actor::Pid;
9use crate::actor::context::RootContext;
10use crate::actor::dispatch::DeadLetterProcess;
11use crate::actor::event_stream::EventStreamProcess;
12use crate::actor::guardian::GuardiansValue;
13use crate::actor::message::EMPTY_MESSAGE_HEADER;
14use crate::actor::process::process_registry::ProcessRegistry;
15use crate::actor::process::ProcessHandle;
16use crate::actor::supervisor::subscribe_supervision;
17use crate::ctxext::extensions::ContextExtensions;
18use crate::event_stream::EventStream;
19
20#[derive(Debug, Clone)]
21struct ActorSystemInner {
22  process_registry: Option<ProcessRegistry>,
23  root_context: Option<RootContext>,
24  event_stream: Arc<EventStream>,
25  guardians: Option<GuardiansValue>,
26  dead_letter: Option<DeadLetterProcess>,
27  extensions: ContextExtensions,
28  config: Config,
29  id: String,
30}
31
32impl ActorSystemInner {
33  async fn new(config: Config) -> Self {
34    let id = Uuid::new_v4().to_string();
35    let myself = ActorSystemInner {
36      id: id.clone(),
37      config,
38      process_registry: None,
39      root_context: None,
40      guardians: None,
41      event_stream: Arc::new(EventStream::new()),
42      // logger: logger.clone(),
43      // log_event_stream,
44      dead_letter: None,
45      extensions: ContextExtensions::new(),
46    };
47    myself
48  }
49}
50
51#[derive(Debug, Clone)]
52pub struct ActorSystem {
53  inner: Arc<Mutex<ActorSystemInner>>,
54}
55
56impl ActorSystem {
57  pub async fn new() -> Self {
58    Self::new_config_options([]).await
59  }
60
61  pub async fn new_config_options(options: impl IntoIterator<Item = ConfigOption>) -> Self {
62    let options = options.into_iter().collect::<Vec<_>>();
63    let config = Self::configure(options);
64    Self::new_with_config(config).await
65  }
66
67  pub async fn new_with_config(config: Config) -> Self {
68    let system = Self {
69      inner: Arc::new(Mutex::new(ActorSystemInner::new(config).await)),
70    };
71    system
72      .set_root_context(RootContext::new(system.clone(), EMPTY_MESSAGE_HEADER.clone(), &[]))
73      .await;
74    system.set_process_registry(ProcessRegistry::new(system.clone())).await;
75    system.set_guardians(GuardiansValue::new(system.clone())).await;
76    system
77      .set_dead_letter(DeadLetterProcess::new(system.clone()).await)
78      .await;
79
80    subscribe_supervision(&system).await;
81
82    // if let Some(metrics_provider) = &config.metrics_provider {
83    //   system.extensions.register(Metrics::new(metrics_provider.clone()));
84    // }
85
86    let event_stream_process = ProcessHandle::new(EventStreamProcess::new(system.clone()));
87    system
88      .get_process_registry()
89      .await
90      .add_process(event_stream_process, "eventstream");
91
92    system
93  }
94
95  pub async fn new_local_pid(&self, id: &str) -> ExtendedPid {
96    let pr = self.get_process_registry().await;
97    let pid = Pid {
98      id: id.to_string(),
99      address: pr.get_address(),
100      request_id: 0,
101    };
102    ExtendedPid::new(pid, self.clone())
103  }
104
105  // pub async fn get_logger(&self) -> Arc<Logger> {
106  //   self.inner.lock().await.logger.clone()
107  // }
108
109  pub async fn get_address(&self) -> String {
110    self.get_process_registry().await.get_address()
111  }
112
113  pub async fn get_config(&self) -> Config {
114    let inner_mg = self.inner.lock().await;
115    inner_mg.config.clone()
116  }
117
118  pub async fn get_root_context(&self) -> RootContext {
119    let inner_mg = self.inner.lock().await;
120    inner_mg.root_context.as_ref().unwrap().clone()
121  }
122
123  pub async fn get_dead_letter(&self) -> ProcessHandle {
124    let inner_mg = self.inner.lock().await;
125    let dead_letter = inner_mg.dead_letter.as_ref().unwrap().clone();
126    ProcessHandle::new(dead_letter)
127  }
128
129  pub async fn get_process_registry(&self) -> ProcessRegistry {
130    let inner_mg = self.inner.lock().await;
131    inner_mg.process_registry.as_ref().unwrap().clone()
132  }
133
134  pub async fn get_event_stream(&self) -> Arc<EventStream> {
135    let inner_mg = self.inner.lock().await;
136    inner_mg.event_stream.clone()
137  }
138
139  pub async fn get_guardians(&self) -> GuardiansValue {
140    let inner_mg = self.inner.lock().await;
141    inner_mg.guardians.as_ref().unwrap().clone()
142  }
143
144  fn configure(options: Vec<ConfigOption>) -> Config {
145    let mut config = Config::default();
146    for option in options {
147      option.apply(&mut config);
148    }
149    config
150  }
151
152  async fn set_root_context(&self, root: RootContext) {
153    let mut inner_mg = self.inner.lock().await;
154    inner_mg.root_context = Some(root);
155  }
156
157  async fn set_process_registry(&self, process_registry: ProcessRegistry) {
158    let mut inner_mg = self.inner.lock().await;
159    inner_mg.process_registry = Some(process_registry);
160  }
161
162  async fn set_guardians(&self, guardians: GuardiansValue) {
163    let mut inner_mg = self.inner.lock().await;
164    inner_mg.guardians = Some(guardians);
165  }
166
167  async fn set_dead_letter(&self, dead_letter: DeadLetterProcess) {
168    let mut inner_mg = self.inner.lock().await;
169    inner_mg.dead_letter = Some(dead_letter);
170  }
171}
172
173#[derive(Debug, Clone)]
174pub struct Config {
175  // pub metrics_provider: Option<Arc<dyn MetricsProvider>>,
176  pub log_prefix: String,
177  pub dispatcher_throughput: usize,
178  pub dead_letter_throttle_interval: Duration,
179  pub dead_letter_throttle_count: usize,
180  pub dead_letter_request_logging: bool,
181  pub developer_supervision_logging: bool,
182  // Other fields...
183}
184
185impl Default for Config {
186  fn default() -> Self {
187    Config {
188      // metrics_provider: None,
189      log_prefix: "".to_string(),
190      dispatcher_throughput: 300,
191      dead_letter_throttle_interval: Duration::from_secs(1),
192      dead_letter_throttle_count: 10,
193      dead_letter_request_logging: false,
194      developer_supervision_logging: false,
195      // Set other default values...
196    }
197  }
198}
199
200pub enum ConfigOption {
201  // SetMetricsProvider(Arc<dyn MetricsProvider>),
202  SetLogPrefix(String),
203  SetDispatcherThroughput(usize),
204  SetDeadLetterThrottleInterval(Duration),
205  SetDeadLetterThrottleCount(usize),
206  // Other options...
207}
208
209impl ConfigOption {
210  fn apply(&self, config: &mut Config) {
211    match self {
212      // ConfigOption::SetMetricsProvider(provider) => {
213      //   config.metrics_provider = Some(Arc::clone(provider));
214      // },
215      ConfigOption::SetLogPrefix(prefix) => {
216        config.log_prefix = prefix.clone();
217      }
218      ConfigOption::SetDispatcherThroughput(throughput) => {
219        config.dispatcher_throughput = *throughput;
220      }
221      ConfigOption::SetDeadLetterThrottleInterval(interval) => {
222        config.dead_letter_throttle_interval = *interval;
223      }
224      ConfigOption::SetDeadLetterThrottleCount(count) => {
225        config.dead_letter_throttle_count = *count;
226      } // Handle other options...
227    }
228  }
229}