1
use std::{fmt::Debug, sync::Arc};
2

            
3
use bonsaidb_utils::fast_async_write;
4
use tokio::sync::oneshot;
5

            
6
use crate::jobs::manager::Manager;
7

            
8
/// he `Id` of an executing task.
9
2903132
#[derive(Debug, Hash, Eq, PartialEq, Clone, Copy)]
10
pub struct Id(pub(crate) u64);
11

            
12
/// References a background task.
13
#[derive(Debug)]
14
pub struct Handle<T, E, Key> {
15
    /// The task's id.
16
    pub id: Id,
17

            
18
    pub(crate) manager: Manager<Key>,
19
    pub(crate) receiver: oneshot::Receiver<Result<T, Arc<E>>>,
20
}
21

            
22
impl<T, E, Key> Handle<T, E, Key>
23
where
24
    T: Send + Sync + 'static,
25
    E: Send + Sync + 'static,
26
    Key: Clone + std::hash::Hash + Eq + Send + Sync + Debug + 'static,
27
{
28
    /// Returns a copy of this handle. When the job is completed, both handles
29
    /// will be able to `receive()` the results.
30
1
    pub async fn clone(&self) -> Self {
31
1
        let mut jobs = fast_async_write!(self.manager.jobs);
32
1
        jobs.create_new_task_handle(self.id, self.manager.clone())
33
1
    }
34

            
35
    /// Waits for the job to complete and returns the result.
36
    ///
37
    /// # Errors
38
    ///
39
    /// Returns an error if the job is cancelled.
40
199943
    pub async fn receive(
41
199943
        self,
42
199943
    ) -> Result<Result<T, Arc<E>>, tokio::sync::oneshot::error::RecvError> {
43
199944
        self.receiver.await
44
199893
    }
45

            
46
    /// Tries to receive the status of the job. If available, it is returned.
47
    /// This function will not block.
48
    ///
49
    /// # Errors
50
    ///
51
    /// Returns an error if the job isn't complete.
52
    ///
53
    /// * [`TryRecvError::Disconnected`](flume::TryRecvError::Disconnected): The job has been cancelled.
54
    /// * [`TryRecvError::Empty`](flume::TryRecvError::Empty): The job has not completed yet.
55
1
    pub fn try_receive(
56
1
        &mut self,
57
1
    ) -> Result<Result<T, Arc<E>>, tokio::sync::oneshot::error::TryRecvError> {
58
1
        self.receiver.try_recv()
59
1
    }
60
}