blob: 56b471facba8dfdff684cc09a1fce6f4782c8d21 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use crate::error::PowerManagerError;
use crate::message::{Message, MessageReturn};
use async_trait::async_trait;
use std::rc::Rc;
/// A trait that all nodes in the PowerManager must implement
#[async_trait(?Send)]
pub trait Node {
/// Return a string to indicate the name of this node
///
/// Each node should use this function to indicate a meaningful name.
/// The name may be used for logging and/or debugging purposes.
fn name(&self) -> String;
/// Handle a new message
///
/// All nodes must implement this message to support communication between nodes. This
/// is the entry point for a Node to receive new messages.
async fn handle_message(&self, msg: &Message) -> Result<MessageReturn, PowerManagerError>;
/// Send a message to another node
///
/// This is implemented as a future to support scenarios where
/// a node wishes to send messages to multiple other nodes.
/// Errors are logged automatically.
async fn send_message(
&self,
node: &Rc<dyn Node>,
msg: &Message,
) -> Result<MessageReturn, PowerManagerError> {
// TODO(fxbug.dev/44484): Ideally we'd use a duration event here. But due to a limitation in the
// Rust tracing library, that would require creating any formatted strings (such as the
// "message" value) unconditionally, even when the tracing category is disabled. To
// avoid that unnecessary computation, just use an instant event.
fuchsia_trace::instant!(
"power_manager:messages",
"message_start",
fuchsia_trace::Scope::Thread,
"message" => format!("{:?}", msg).as_str(),
"source_node" => self.name().as_str(),
"dest_node" => node.name().as_str()
);
let result = node.handle_message(msg).await;
fuchsia_trace::instant!(
"power_manager:messages",
"message_result",
fuchsia_trace::Scope::Thread,
"message" => format!("{:?}", msg).as_str(),
"source_node" => self.name().as_str(),
"dest_node" => node.name().as_str(),
"result" => format!("{:?}", result).as_str()
);
result
}
}