runledger_postgres/jobs/types/
lifecycle.rs1use std::time::Duration;
2
3use chrono::{DateTime, Utc};
4use runledger_core::jobs::{JobFailureKind, JobRetryTiming, JobStage, JobTypeName};
5use serde_json::Value;
6use sqlx::types::Uuid;
7
8#[derive(Clone, Copy, Debug, Eq, PartialEq)]
14pub struct JobLeaseIdentity<'a> {
15 pub job_id: Uuid,
16 pub run_number: i32,
17 pub attempt: i32,
18 pub worker_id: &'a str,
19}
20
21impl<'a> JobLeaseIdentity<'a> {
22 #[must_use]
24 pub const fn new(job_id: Uuid, run_number: i32, attempt: i32, worker_id: &'a str) -> Self {
25 Self {
26 job_id,
27 run_number,
28 attempt,
29 worker_id,
30 }
31 }
32}
33
34#[derive(Clone, Debug)]
43pub struct JobRunningUpdate<'a> {
44 pub progress_done: Option<i64>,
45 pub progress_total: Option<i64>,
46 pub checkpoint: Option<&'a Value>,
47}
48
49#[derive(Clone, Debug)]
56pub struct JobOrdinaryProgressUpdate<'a> {
57 pub progress_done: Option<i64>,
58 pub progress_total: Option<i64>,
59 pub checkpoint: Option<&'a Value>,
60}
61
62#[deprecated(
71 since = "0.11.0",
72 note = "use JobRunningUpdate with mark_job_running for RUNNING, or JobOrdinaryProgressUpdate with update_job_ordinary_progress for ordinary progress"
73)]
74#[derive(Clone, Debug)]
75pub struct JobProgressUpdate<'a> {
76 pub stage: Option<JobStage>,
77 pub progress_done: Option<i64>,
78 pub progress_total: Option<i64>,
79 pub checkpoint: Option<&'a Value>,
80}
81
82#[derive(Clone, Debug)]
83pub struct JobCompletionUpdate<'a> {
84 pub progress_done: Option<i64>,
85 pub progress_total: Option<i64>,
86 pub checkpoint: Option<&'a Value>,
87 pub output: Option<&'a Value>,
88}
89
90#[derive(Clone, Debug)]
92pub struct JobContinuationUpdate<'a> {
93 pub delay: Duration,
98 pub progress_done: Option<i64>,
99 pub progress_total: Option<i64>,
100 pub checkpoint: Option<&'a Value>,
101}
102
103#[derive(Clone, Debug)]
104#[non_exhaustive]
105pub struct JobContinuationOutcome {
106 pub job_id: Uuid,
107 pub job_type: JobTypeName,
108 pub organization_id: Option<Uuid>,
109 pub completed_run_number: i32,
111 pub next_run_number: i32,
113 pub attempt: i32,
114 pub max_attempts: i32,
115 pub next_run_at: DateTime<Utc>,
116 pub progress_done: Option<i64>,
117 pub progress_total: Option<i64>,
118}
119
120#[derive(Clone, Debug)]
121#[non_exhaustive]
122pub struct JobSuccessCompletionOutcome {
123 pub job_id: Uuid,
124 pub job_type: JobTypeName,
125 pub organization_id: Option<Uuid>,
126 pub run_number: i32,
127 pub attempt: i32,
128 pub max_attempts: i32,
129 pub progress_done: Option<i64>,
130 pub progress_total: Option<i64>,
131}
132
133#[derive(Clone, Debug)]
138#[non_exhaustive]
139pub struct JobFailureUpdate<'a> {
140 pub kind: JobFailureKind,
141 pub code: &'a str,
142 pub message: &'a str,
143 pub retry_timing: Option<JobRetryTiming>,
145 pub policy_retry_delay_ms: Option<i32>,
147}
148
149impl<'a> JobFailureUpdate<'a> {
150 #[must_use]
153 pub const fn new(
154 kind: JobFailureKind,
155 code: &'a str,
156 message: &'a str,
157 policy_retry_delay_ms: Option<i32>,
158 ) -> Self {
159 Self {
160 kind,
161 code,
162 message,
163 retry_timing: None,
164 policy_retry_delay_ms,
165 }
166 }
167
168 #[must_use]
170 pub const fn with_retry_timing(mut self, retry_timing: JobRetryTiming) -> Self {
171 self.retry_timing = Some(retry_timing);
172 self
173 }
174}
175
176#[derive(Clone, Debug, Eq, PartialEq)]
178#[non_exhaustive]
179pub enum JobFailureCompletionDisposition {
180 RetryScheduled {
182 retry_delay_ms: i32,
184 next_run_at: DateTime<Utc>,
186 },
187 RetryScheduledAt {
189 requested_retry_at: DateTime<Utc>,
192 next_run_at: DateTime<Utc>,
194 },
195 DeadLettered {
196 reason: runledger_core::jobs::JobDeadLetterReason,
197 },
198}
199
200#[derive(Clone, Debug)]
201#[non_exhaustive]
202pub struct JobFailureCompletionOutcome {
203 pub job_id: Uuid,
204 pub job_type: JobTypeName,
205 pub organization_id: Option<Uuid>,
206 pub run_number: i32,
207 pub attempt: i32,
208 pub max_attempts: i32,
209 pub failure_kind: JobFailureKind,
210 pub failure_code: String,
211 pub failure_message: String,
212 pub checkpoint: Option<Value>,
214 pub disposition: JobFailureCompletionDisposition,
215}
216
217#[cfg(test)]
218mod job_lease_identity_tests {
219 use super::*;
220
221 #[test]
222 fn construction_retains_each_lease_fence() {
223 let identity = JobLeaseIdentity::new(Uuid::nil(), 7, 3, "worker-identity-test");
224
225 assert_eq!(identity.job_id, Uuid::nil());
226 assert_eq!(identity.run_number, 7);
227 assert_eq!(identity.attempt, 3);
228 assert_eq!(identity.worker_id, "worker-identity-test");
229 }
230}