1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
mod child_id;
mod child_spec;
mod restart_intensity;
mod restart_strategy;
mod sup_spec;

use agner_actors::{ActorID, Exit, System};
use agner_utils::result_err_flatten::ResultErrFlattenIn;
pub use child_id::ChildID;
pub use child_spec::{ChildSpec, ChildType};
pub use restart_intensity::RestartIntensity;
pub use restart_strategy::{AllForOne, OneForOne, RestForOne};
pub use sup_spec::SupSpec;
pub mod supervisor;

pub mod plumbing {
    pub use super::restart_intensity::{DurationToInstant, ElapsedSince, RestartStats};
    pub use super::restart_strategy::{Action, Decider, RestartStrategy};
}

pub use supervisor::run;
use tokio::sync::oneshot;

use self::supervisor::SupervisorError;

pub async fn start_child<ID>(
    system: &System,
    sup: ActorID,
    child_spec: ChildSpec<ID>,
) -> Result<ActorID, SupervisorError>
where
    ID: ChildID,
{
    let (tx, rx) = oneshot::channel();
    let message = supervisor::Message::StartChild(child_spec, tx);
    system.send(sup, message).await;
    rx.await.err_flatten_in()
}

pub async fn terminate_child<ID>(
    system: &System,
    sup: ActorID,
    child_id: ID,
) -> Result<Exit, SupervisorError>
where
    ID: ChildID,
{
    let (tx, rx) = oneshot::channel();
    let message = supervisor::Message::TerminateChild(child_id, tx);
    system.send(sup, message).await;
    rx.await.err_flatten_in()
}

pub async fn which_children<ID>(
    system: &System,
    sup: ActorID,
) -> Result<Vec<(ID, ActorID)>, SupervisorError>
where
    ID: ChildID,
{
    let (tx, rx) = oneshot::channel();
    let message = supervisor::Message::WhichChildren(tx);
    system.send(sup, message).await;
    rx.await.map_err(Into::into)
}