Lucas Soriano del Pino
3 years ago
4 changed files with 63 additions and 14 deletions
@ -0,0 +1,57 @@ |
|||
use async_trait::async_trait; |
|||
|
|||
#[async_trait] |
|||
pub trait SendAsyncSafe<M, R> |
|||
where |
|||
M: xtra::Message<Result = R>, |
|||
{ |
|||
/// Send a message to an actor without waiting for them to handle
|
|||
/// it.
|
|||
///
|
|||
/// As soon as this method returns, we know if the receiving actor
|
|||
/// is alive. If they are, the message we are sending will
|
|||
/// eventually be handled by them, but we don't wait for them to
|
|||
/// do so.
|
|||
async fn send_async_safe(&self, msg: M) -> Result<(), xtra::Disconnected>; |
|||
} |
|||
|
|||
#[async_trait] |
|||
impl<A, M> SendAsyncSafe<M, ()> for xtra::Address<A> |
|||
where |
|||
A: xtra::Handler<M>, |
|||
M: xtra::Message<Result = ()>, |
|||
{ |
|||
async fn send_async_safe(&self, msg: M) -> Result<(), xtra::Disconnected> { |
|||
#[allow(clippy::disallowed_method)] |
|||
self.do_send_async(msg).await |
|||
} |
|||
} |
|||
|
|||
#[async_trait] |
|||
impl<A, M, E> SendAsyncSafe<M, Result<(), E>> for xtra::Address<A> |
|||
where |
|||
A: xtra::Handler<M>, |
|||
M: xtra::Message<Result = Result<(), E>>, |
|||
E: std::error::Error + Send, |
|||
{ |
|||
async fn send_async_safe(&self, msg: M) -> Result<(), xtra::Disconnected> { |
|||
if !self.is_connected() { |
|||
return Err(xtra::Disconnected); |
|||
} |
|||
|
|||
let send_fut = self.send(msg); |
|||
|
|||
#[allow(clippy::disallowed_method)] |
|||
tokio::spawn(async { |
|||
let e = match send_fut.await { |
|||
Ok(Err(e)) => format!("{:#}", e), |
|||
Err(e) => format!("{:#}", e), |
|||
Ok(Ok(())) => return, |
|||
}; |
|||
|
|||
tracing::warn!("Async message invocation failed: {:#}", e) |
|||
}); |
|||
|
|||
Ok(()) |
|||
} |
|||
} |
Loading…
Reference in new issue