about summary refs log tree commit diff
path: root/util/src/queue.rs
blob: c880597da9b95292d50074373f9495308c5bdd55 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use futures_util::Stream;
use std::pin::Pin;
use uuid::Uuid;

#[async_trait::async_trait]
/// A job queue that can store and return jobs.
pub trait JobQueue<T: JobItem>: Send + Sync + Sized + Clone + 'static {
    /// A type of job object that will be returned by the queue.
    type Job: Job<T, Self>;
    /// Error type that the queue can produce in its work.
    type Error: std::error::Error + Send + Sync + Sized;

    /// Get one item from the job queue, if the job queue has pending
    /// items available.
    ///
    /// # Errors
    ///
    /// Returns an error if a job queue failed in some way. Having no
    /// items is not a failure, in which case `Ok(None)` is returned.
    async fn get_one(&self) -> Result<Option<Self::Job>, Self::Error>;
    /// Put an item into a job queue, returning its UUID.
    async fn put(&self, item: &T) -> Result<Uuid, Self::Error>;

    /*
    /// Check the amount of pending and stuck items in the job queue.
    async fn len(&self) -> Result<(usize, usize), Self::Error>;
    /// Returns whether the job queue has some pending items.
    async fn is_empty(&self) -> Result<bool, Self::Error> {
        Ok(self.len().await?.0 == 0)
    }
    /// Returns whether the job queue has some stuck items that
    /// require manual cleanup.
    async fn has_stuck(&self) -> Result<bool, Self::Error> {
        Ok(self.len().await?.1 > 0)
    }
    */

    /// Consume the job queue object and return a stream of unstuck
    /// items from the job queue.
    ///
    /// Note that one item may be returned several times if it is not
    /// marked as done.
    async fn into_stream(self) -> Result<Pin<Box<dyn Stream<Item = Result<Self::Job, Self::Error>> + Send>>, Self::Error>;
}

#[async_trait::async_trait]
/// A job description yielded from a job queue.
///
/// # Implementors
///
/// On [`Drop`], the job should be returned to a job queue. If your
/// job queue tracks attempts, the counter should be incremented by
/// one.
///
/// Figuring how to do this asynchronously from a synchronous trait
/// is left as an exercise to the reader.
pub trait Job<T: JobItem, Q: JobQueue<T>>: Send + Sync + Sized {
    /// Get the object describing the task itself.
    fn job(&self) -> &T;
    /// Mark the job as done and remove it from the job queue.
    async fn done(self) -> Result<(), Q::Error>;
}

/// An object describing the job itself, returned as part of a
/// [`Job`].
pub trait JobItem: Send + Sync + Sized + std::fmt::Debug {}