runtime: move logger to use a Receiver<LogMessage>
This loses the ability to drain and display all pending log messages on
shutdown, but is worth it for clearer code.
//! Logging pseudo-Node functionality.
-use crate::RuntimeProxy;
-use log::{error, info};
+use crate::{
+ io::{Receiver, ReceiverExt},
+ RuntimeProxy,
+};
+use log::{error, info, warn};
use oak_abi::OakStatus;
+use oak_io::{handle::ReadHandle, OakError};
use oak_services::proto::oak::log::{Level, LogMessage};
-use prost::Message;
use std::string::String;
use tokio::sync::oneshot;
@@ -47,13 +50,9 @@ impl super::Node for LogNode {
handle: oak_abi::Handle,
_notify_receiver: oneshot::Receiver<()>,
) {
- 'wait: loop {
- let result = runtime.wait_on_channels(&[handle]);
-
- // Read all available log messages (even if the Runtime is terminating).
- 'read: loop {
- match runtime.channel_read(handle) {
- Ok(Some(message)) => match LogMessage::decode(&*message.bytes) {
+ let receiver = Receiver::<LogMessage>::new(ReadHandle { handle });
+ loop {
+ match receiver.receive(&runtime) {
Ok(msg) => {
// Log messages that arrive from Oak applications over a logging channel
// are controlled by IFC, and so need to be emitted independently of
@@ -71,28 +70,21 @@ impl super::Node for LogNode {
msg.message
);
}
- Err(error) => {
- error!("{} Could not parse LogMessage: {}", self.node_name, error)
- }
- },
- Ok(None) => {
- // No more log messages to read, go back to waiting.
- break 'read;
- }
- Err(OakStatus::ErrChannelClosed) => {
- info!("{} channel closed by remote", self.node_name);
- break 'wait;
+ // Recoverable errors:
+ Err(OakError::ProtobufDecodeError(err)) => {
+ warn!("{} failed to decode log message: {:?}", self.node_name, err);
}
- Err(status) => {
- error!("{} Failed channel read: {:?}", self.node_name, status);
- break 'wait;
+ // Errors that lead to Node termination:
+ Err(OakError::OakStatus(OakStatus::ErrTerminated)) => break,
+ Err(OakError::OakStatus(OakStatus::ErrChannelClosed)) => {
+ info!("{} channel closed", self.node_name);
+ break;
}
+ Err(err) => {
+ error!("{} failed channel receive: {:?}", self.node_name, err);
+ break;
}
}
-
- if result == Err(OakStatus::ErrTerminated) {
- break 'wait;
- }
}
info!("{} logger execution complete", self.node_name);
let _ = runtime.channel_close(handle);
