Skip to main content

awa_worker/
events.rs

1use awa_model::JobRow;
2use chrono::{DateTime, Utc};
3use std::future::Future;
4use std::pin::Pin;
5use std::sync::Arc;
6use std::time::Duration;
7
8/// Typed lifecycle event for a specific job argument type.
9#[derive(Debug, Clone)]
10pub enum JobEvent<T> {
11    /// Job completed successfully.
12    Completed {
13        args: T,
14        job: JobRow,
15        duration: Duration,
16    },
17    /// Job failed but will be retried later.
18    Retried {
19        args: T,
20        job: JobRow,
21        error: String,
22        attempt: i16,
23        next_run_at: DateTime<Utc>,
24    },
25    /// Job exhausted its retry budget and moved to `failed`.
26    Exhausted {
27        args: T,
28        job: JobRow,
29        error: String,
30        attempt: i16,
31    },
32    /// Job was cancelled by the handler.
33    Cancelled {
34        args: T,
35        job: JobRow,
36        reason: String,
37    },
38}
39
40impl<T> JobEvent<T> {
41    /// The job snapshot associated with this event.
42    pub fn job(&self) -> &JobRow {
43        match self {
44            JobEvent::Completed { job, .. }
45            | JobEvent::Retried { job, .. }
46            | JobEvent::Exhausted { job, .. }
47            | JobEvent::Cancelled { job, .. } => job,
48        }
49    }
50}
51
52/// Untyped lifecycle event keyed only by job kind.
53#[derive(Debug, Clone)]
54pub enum UntypedJobEvent {
55    /// Job completed successfully.
56    Completed { job: JobRow, duration: Duration },
57    /// Job failed but will be retried later.
58    Retried {
59        job: JobRow,
60        error: String,
61        attempt: i16,
62        next_run_at: DateTime<Utc>,
63    },
64    /// Job exhausted its retry budget and moved to `failed`.
65    Exhausted {
66        job: JobRow,
67        error: String,
68        attempt: i16,
69    },
70    /// Job was cancelled by the handler.
71    Cancelled { job: JobRow, reason: String },
72}
73
74impl UntypedJobEvent {
75    /// The job snapshot associated with this event.
76    pub fn job(&self) -> &JobRow {
77        match self {
78            UntypedJobEvent::Completed { job, .. }
79            | UntypedJobEvent::Retried { job, .. }
80            | UntypedJobEvent::Exhausted { job, .. }
81            | UntypedJobEvent::Cancelled { job, .. } => job,
82        }
83    }
84
85    pub(crate) fn into_typed<T>(self, args: T) -> JobEvent<T> {
86        match self {
87            UntypedJobEvent::Completed { job, duration } => JobEvent::Completed {
88                args,
89                job,
90                duration,
91            },
92            UntypedJobEvent::Retried {
93                job,
94                error,
95                attempt,
96                next_run_at,
97            } => JobEvent::Retried {
98                args,
99                job,
100                error,
101                attempt,
102                next_run_at,
103            },
104            UntypedJobEvent::Exhausted {
105                job,
106                error,
107                attempt,
108            } => JobEvent::Exhausted {
109                args,
110                job,
111                error,
112                attempt,
113            },
114            UntypedJobEvent::Cancelled { job, reason } => JobEvent::Cancelled { args, job, reason },
115        }
116    }
117}
118
119pub(crate) type BoxedLifecycleFuture = Pin<Box<dyn Future<Output = ()> + Send + 'static>>;
120pub(crate) type BoxedUntypedEventHandler =
121    Arc<dyn Fn(UntypedJobEvent) -> BoxedLifecycleFuture + Send + Sync + 'static>;