use std::fmt; use xtra::prelude::MessageChannel; use xtra::{Handler, KeepRunning}; /// A forwarding actor that only forwards [`Result::Ok`] values and shuts itself down upon the first /// error. pub struct Actor { forward: Box>, } impl Actor { pub fn new(forward: Box>) -> Self { Self { forward } } } pub struct Message(pub Result); impl xtra::Message for Message where TOk: Send + 'static, TErr: Send + 'static, { type Result = KeepRunning; } #[async_trait::async_trait] impl Handler> for Actor where TOk: xtra::Message + Send + 'static, TErr: fmt::Display + Send + 'static, { async fn handle( &mut self, Message(result): Message, _: &mut xtra::Context, ) -> KeepRunning { let ok = match result { Ok(ok) => ok, Err(e) => { tracing::error!("Stopping forwarding due to error: {}", e); return KeepRunning::StopSelf; } }; if let Err(xtra::Disconnected) = self.forward.send(ok).await { tracing::info!("Target actor disappeared, stopping"); return KeepRunning::StopSelf; } KeepRunning::Yes } } impl xtra::Actor for Actor {}