zestors/spawning/
functions.rs

1use crate::all::*;
2use futures::Future;
3
4/// Same as [`spawn_with`] but with a default [`Link`] and [`InboxType::Config`].
5/// 
6/// # Usage
7/// ```
8/// # tokio_test::block_on(main());
9/// use zestors::prelude::*;
10/// 
11/// # async fn main() {
12/// let (child, address) = spawn(|inbox: Inbox<()>| async move {
13///     todo!()
14/// });
15/// # }
16/// ```
17pub fn spawn<I, E, Fun, Fut>(function: Fun) -> (Child<E, I>, Address<I>)
18where
19    Fun: FnOnce(I) -> Fut + Send + 'static,
20    Fut: Future<Output = E> + Send,
21    I: InboxType,
22    I::Config: Default,
23    E: Send + 'static,
24{
25    spawn_with(Default::default(), Default::default(), function)
26}
27
28/// Spawn an actor with the given function using the [`Link`] and [`InboxType::Config`].
29/// 
30/// # Usage
31/// ```
32/// # tokio_test::block_on(main());
33/// use zestors::prelude::*;
34/// 
35/// # async fn main() {
36/// let (child, address) = spawn_with(
37///     Link::default(), 
38///     Capacity::default(), 
39///     |inbox: Inbox<()>| async move {
40///         todo!()
41///     }
42/// );
43/// # }
44/// ```
45pub fn spawn_with<I, E, Fun, Fut>(
46    link: Link,
47    config: I::Config,
48    function: Fun,
49) -> (Child<E, I>, Address<I>)
50where
51    Fun: FnOnce(I) -> Fut + Send + 'static,
52    Fut: Future<Output = E> + Send,
53    I: InboxType,
54    E: Send + 'static,
55{
56    let (channel, inbox) = I::init_single_inbox(config, 1, ActorId::generate());
57    // let inbox = I::from_channel(channel.clone());
58    let handle = tokio::task::spawn(async move { function(inbox).await });
59    (
60        Child::new(channel.clone(), handle, link),
61        Address::from_channel(channel),
62    )
63}
64
65/// Spawn an actor consisting of multiple processes with the given function using a default
66/// [`Link`] and [`InboxType::Config`].
67///
68/// # Usage
69/// ```
70/// # tokio_test::block_on(main());
71/// use zestors::prelude::*;
72/// 
73/// # async fn main() {
74/// let (child, address) = spawn_many(0..5, |i: u32, inbox: Inbox<()>| async move {
75///     todo!()
76/// });
77/// # }
78/// ```
79pub fn spawn_many<I, E, Itm, Fun, Fut>(
80    iter: impl ExactSizeIterator<Item = Itm>,
81    function: Fun,
82) -> (ChildPool<E, I>, Address<I>)
83where
84    Fun: FnOnce(Itm, I) -> Fut + Clone + Send + 'static,
85    Fut: Future<Output = E> + Send,
86    I: MultiProcessInbox,
87    I::Config: Default,
88    E: Send + 'static,
89    Itm: Send + 'static,
90{
91    spawn_many_with(Default::default(), Default::default(), iter, function)
92}
93
94/// Spawn an actor consisting of multiple processes with the given function using a custom
95/// [`Link`] and [`InboxType::Config`].
96///
97/// # Usage
98/// ```
99/// # tokio_test::block_on(main());
100/// use zestors::prelude::*;
101/// 
102/// # async fn main() {
103/// let (child, address) = spawn_many_with(
104///     Link::default(), 
105///     Capacity::default(), 
106///     0..5, 
107///     |i: u32, inbox: Inbox<()>| async move {
108///         todo!()
109///     }
110/// );
111/// # }
112/// ```
113pub fn spawn_many_with<I, E, Itm, Fun, Fut>(
114    link: Link,
115    config: I::Config,
116    iter: impl ExactSizeIterator<Item = Itm>,
117    function: Fun,
118) -> (ChildPool<E, I>, Address<I>)
119where
120    Fun: FnOnce(Itm, I) -> Fut + Clone + Send + 'static,
121    Fut: Future<Output = E> + Send,
122    I: MultiProcessInbox,
123    E: Send + 'static,
124    Itm: Send + 'static,
125{
126    let channel = I::init_multi_inbox(config, iter.len(), 1, ActorId::generate());
127    let handles = iter
128        .map(|i| {
129            let fun = function.clone();
130            let inbox = I::from_channel(channel.clone());
131            tokio::task::spawn(async move { fun(i, inbox).await })
132        })
133        .collect::<Vec<_>>();
134    (
135        Child::new(channel.clone(), handles, link),
136        Address::from_channel(channel),
137    )
138}