fast_pull/core/
handle.rs

1extern crate alloc;
2use alloc::sync::Arc;
3use tokio::{
4    sync::watch,
5    task::{JoinError, JoinHandle},
6};
7
8#[derive(Debug)]
9pub struct SharedHandle<T> {
10    rx: watch::Receiver<Option<Result<T, Arc<JoinError>>>>,
11}
12
13impl<T> SharedHandle<T>
14where
15    T: Clone + Send + Sync + 'static,
16{
17    pub fn new(handle: JoinHandle<T>) -> Self {
18        let (tx, rx) = watch::channel(None);
19        tokio::spawn(async move {
20            let _ = tx.send(Some(handle.await.map_err(Arc::from)));
21        });
22        Self { rx }
23    }
24
25    pub async fn join(&self) -> Result<T, Arc<JoinError>> {
26        let mut rx = self.rx.clone();
27        loop {
28            if let Some(res) = rx.borrow_and_update().clone() {
29                return res;
30            }
31            if rx.changed().await.is_err() {
32                return match rx.borrow().clone() {
33                    Some(res) => res,
34                    None => panic!(
35                        "SharedHandle background task panicked or was cancelled unexpectedly"
36                    ),
37                };
38            }
39        }
40    }
41}