hyperactor/
supervision.rs

1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the root directory of this source tree.
7 */
8
9//! Messages used in supervision.
10
11use std::fmt;
12use std::fmt::Debug;
13
14use derivative::Derivative;
15use serde::Deserialize;
16use serde::Serialize;
17
18use crate as hyperactor; // for macros
19use crate::Named;
20use crate::actor::ActorStatus;
21use crate::attrs::Attrs;
22use crate::reference::ActorId;
23
24/// This is the local actor supervision event. Child actor will propagate this event to its parent.
25#[derive(Clone, Debug, Derivative, Serialize, Deserialize, Named)]
26#[derivative(PartialEq, Eq)]
27pub struct ActorSupervisionEvent {
28    /// The actor id of the child actor where the event is triggered.
29    pub actor_id: ActorId,
30    /// Status of the child actor.
31    pub actor_status: ActorStatus,
32    /// If this event is associated with a message, the message headers.
33    #[derivative(PartialEq = "ignore")]
34    pub message_headers: Option<Attrs>,
35    /// Optional supervision event that caused this event, for recursive propagation.
36    pub caused_by: Option<Box<ActorSupervisionEvent>>,
37}
38
39impl ActorSupervisionEvent {
40    /// Compute an actor status from this event, ensuring that "caused-by"
41    /// events are included in failure states. This should be used as the
42    /// actor status when reporting events to users.
43    pub fn status(&self) -> ActorStatus {
44        match &self.actor_status {
45            ActorStatus::Failed(msg) => {
46                ActorStatus::Failed(format!("{}: {}", self.to_string(), msg))
47            }
48            status => status.clone(),
49        }
50    }
51}
52
53impl std::error::Error for ActorSupervisionEvent {}
54
55impl fmt::Display for ActorSupervisionEvent {
56    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57        write!(f, "{}: {}", self.actor_id, self.actor_status)?;
58        if let Some(message_headers) = &self.message_headers {
59            let headers = serde_json::to_string(&message_headers)
60                .expect("could not serialize message headers");
61            write!(f, " (headers: {})", headers)?;
62        }
63        if let Some(caused_by) = &self.caused_by {
64            write!(f, ": caused by: {})", caused_by)?;
65        }
66        Ok(())
67    }
68}