Skip to main content

acktor/message/
future_result.rs

1use std::fmt::{self, Debug};
2use std::future;
3use std::pin::Pin;
4
5use tracing::Instrument;
6
7use super::{Message, MessageResponse};
8use crate::actor::Actor;
9use crate::channel::oneshot;
10use crate::utils::ShortName;
11
12/// A helper type which wraps the result of a message handler as a future which runs off the
13/// mailbox.
14///
15/// Return [`FutureMessageResult`] from a handler when the work must be awaited but should not
16/// stall the actor. The inner future resolves to `M::Result`, which is what the caller ultimately
17/// receives.
18///
19/// The inner future is spawned into the Tokio runtime and is detached from the actor's
20/// lifecycle. It continues running even after the actor is stopped or terminated.
21pub struct FutureMessageResult<M>
22where
23    M: Message,
24{
25    future: Pin<Box<dyn Future<Output = M::Result> + Send>>,
26}
27
28impl<M> Debug for FutureMessageResult<M>
29where
30    M: Message,
31{
32    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33        f.write_fmt(format_args!("{}", ShortName::of::<Self>()))
34    }
35}
36
37impl<M> FutureMessageResult<M>
38where
39    M: Message,
40{
41    /// Wrap a future that produces the handler's result.
42    pub fn new<F>(future: F) -> Self
43    where
44        F: Future<Output = M::Result> + Send + 'static,
45    {
46        Self {
47            future: Box::pin(future),
48        }
49    }
50}
51
52impl<A, M> MessageResponse<A, M> for FutureMessageResult<M>
53where
54    A: Actor,
55    M: Message,
56{
57    fn handle(
58        self,
59        _ctx: &mut A::Context,
60        tx: Option<oneshot::Sender<M::Result>>,
61    ) -> impl Future<Output = ()> + Send {
62        tokio::spawn(
63            async move {
64                let result = self.future.await;
65                if let Some(tx) = tx {
66                    let _ = tx.send(result);
67                }
68            }
69            .in_current_span(),
70        );
71        future::ready(())
72    }
73}