Skip to main content

bombay/runtime/
outcome.rs

1//! Generation-safe observation of Tokio actor-task completion.
2
3use behavior::{Address, Crash, Exit};
4use bombay_engine::{RunError, RunExit};
5
6/// Every terminal state of an actor task.
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum TaskOutcome<T> {
9    /// The actor future returned its domain result.
10    Returned(T),
11    /// The actor future unwound with a panic.
12    Panicked,
13    /// The actor future was aborted before returning.
14    Cancelled,
15}
16
17pub(crate) trait IntoPeerOutcome<A: Address> {
18    fn peer_outcome(&self) -> Result<Exit<A>, Crash>;
19}
20
21impl<A: Address, B, E> IntoPeerOutcome<A> for Result<RunExit<Exit<A>>, RunError<B, E>> {
22    fn peer_outcome(&self) -> Result<Exit<A>, Crash> {
23        match self {
24            Ok(RunExit::Stopped(exit)) => Ok(*exit),
25            Ok(RunExit::EnvironmentClosed) => Ok(Exit::Collected),
26            Err(RunError::Behavior(_)) => Err(Crash::Failed),
27            Err(RunError::Environment(_)) => Err(Crash::EnvironmentFailed),
28            Err(RunError::Poisoned) => Err(Crash::Panicked),
29        }
30    }
31}
32
33pub(crate) fn classify_task<A: Address, T: IntoPeerOutcome<A>>(
34    outcome: &TaskOutcome<T>,
35) -> Result<Exit<A>, Crash> {
36    match outcome {
37        TaskOutcome::Returned(outcome) => outcome.peer_outcome(),
38        TaskOutcome::Panicked => Err(Crash::Panicked),
39        TaskOutcome::Cancelled => Err(Crash::Cancelled),
40    }
41}