Skip to main content

compio_actor\cluster/
mod.rs

1//! Actor cluster, registry, and spawn configuration.
2
3mod current;
4mod registry;
5mod spawn;
6
7use std::{
8    borrow::Cow,
9    io,
10    sync::{Arc, Mutex},
11};
12
13use compio_dispatcher::Dispatcher;
14use registry::Registry;
15#[doc(inline)]
16pub use spawn::{Spawn, SpawnError, SpawnFuture, SpawnResult};
17
18use crate::{Actor, Mailbox};
19
20/// A set of Compio workers on which actors are placed.
21#[derive(Clone)]
22pub struct Cluster {
23    inner: Arc<ClusterInner>,
24}
25
26struct ClusterInner {
27    dispatcher: Mutex<Option<Dispatcher>>,
28    registry: Registry,
29}
30
31impl Cluster {
32    /// Creates a cluster using the dispatcher's defaults.
33    pub fn new() -> io::Result<Self> {
34        Dispatcher::new().map(Self::from_dispatcher)
35    }
36
37    /// Creates a cluster from a configured dispatcher.
38    pub fn from_dispatcher(dispatcher: Dispatcher) -> Self {
39        Self {
40            inner: Arc::new(ClusterInner {
41                dispatcher: Mutex::new(Some(dispatcher)),
42                registry: Registry::default(),
43            }),
44        }
45    }
46
47    /// Configures an actor spawn operation.
48    ///
49    /// The return type is a configurable future implementing [`IntoFuture`].
50    /// See [`Spawn`] for detail.
51    pub fn spawn<A, F>(&self, factory: F, arguments: A::Arguments) -> Spawn<'_, A, F>
52    where
53        A: Actor,
54        F: FnOnce() -> A + Send + 'static,
55    {
56        Spawn::new(self, factory, arguments)
57    }
58
59    /// Looks up a named actor of type `A`.
60    pub fn lookup<A, N>(&self, name: N) -> Option<Mailbox<A>>
61    where
62        A: Actor,
63        N: Into<Cow<'static, str>>,
64    {
65        let name = name.into();
66        self.inner.registry.get(&name)
67    }
68
69    /// Stops the dispatcher workers and waits for their threads to exit.
70    pub async fn join(self) -> io::Result<()> {
71        let dispatcher = self.inner.dispatcher.lock().unwrap().take();
72        match dispatcher {
73            Some(dispatcher) => dispatcher.join().await,
74            None => Ok(()),
75        }
76    }
77}