apalis_core/task/
builder.rs1use crate::task::{
28 Parts, Task, attempt::Attempt, extensions::Extensions, metadata::MetadataExt, status::Status,
29 task_id::TaskId,
30};
31use std::time::{Duration, SystemTime, UNIX_EPOCH};
32
33#[derive(Debug)]
35pub struct TaskBuilder<Args, Ctx, IdType> {
36 pub(super) args: Args,
37 #[doc(hidden)]
39 pub ctx: Ctx,
40 pub(super) data: Extensions,
41 pub(super) task_id: Option<TaskId<IdType>>,
42 pub(super) attempt: Option<Attempt>,
43 pub(super) status: Option<Status>,
44 pub(super) run_at: Option<u64>,
45}
46
47impl<Args, Ctx, IdType> TaskBuilder<Args, Ctx, IdType> {
48 #[must_use]
50 pub fn new(args: Args) -> Self
51 where
52 Ctx: Default,
53 {
54 Self {
55 args,
56 ctx: Default::default(),
57 data: Extensions::default(),
58 task_id: None,
59 attempt: None,
60 status: None,
61 run_at: None,
62 }
63 }
64
65 #[must_use]
67 pub fn with_ctx(mut self, ctx: Ctx) -> Self {
68 self.ctx = ctx;
69 self
70 }
71
72 #[must_use]
74 pub fn with_data(mut self, data: Extensions) -> Self {
75 self.data = data;
76 self
77 }
78
79 #[must_use]
81 pub fn data<D: Clone + Send + Sync + 'static>(mut self, value: D) -> Self {
82 self.data.insert(value);
83 self
84 }
85
86 #[must_use]
88 pub fn meta<M>(mut self, value: M) -> Self
89 where
90 Ctx: MetadataExt<M>,
91 {
92 self.ctx
93 .inject(value)
94 .unwrap_or_else(|_| panic!("Failed to inject item into context"));
95 self
96 }
97
98 #[must_use]
100 pub fn with_task_id(mut self, task_id: TaskId<IdType>) -> Self {
101 self.task_id = Some(task_id);
102 self
103 }
104
105 #[must_use]
107 pub fn with_attempt(mut self, attempt: Attempt) -> Self {
108 self.attempt = Some(attempt);
109 self
110 }
111
112 #[must_use]
114 pub fn with_status(mut self, status: Status) -> Self {
115 self.status = Some(status);
116 self
117 }
118
119 #[must_use]
121 pub fn run_at_timestamp(mut self, timestamp: u64) -> Self {
122 self.run_at = Some(timestamp);
123 self
124 }
125
126 #[must_use]
128 pub fn run_at_time(mut self, time: SystemTime) -> Self {
129 let timestamp = time
130 .duration_since(UNIX_EPOCH)
131 .expect("Time went backwards")
132 .as_secs();
133 self.run_at = Some(timestamp);
134 self
135 }
136
137 #[must_use]
139 pub fn run_after(mut self, delay: Duration) -> Self {
140 let now = SystemTime::now();
141 let run_time = now + delay;
142 let timestamp = run_time
143 .duration_since(UNIX_EPOCH)
144 .expect("Time went backwards")
145 .as_secs();
146 self.run_at = Some(timestamp);
147 self
148 }
149
150 #[must_use]
152 pub fn run_in_seconds(self, seconds: u64) -> Self {
153 self.run_after(Duration::from_secs(seconds))
154 }
155
156 #[must_use]
158 pub fn run_in_minutes(self, minutes: u64) -> Self {
159 self.run_after(Duration::from_secs(minutes * 60))
160 }
161
162 #[must_use]
164 pub fn run_in_hours(self, hours: u64) -> Self {
165 self.run_after(Duration::from_secs(hours * 3600))
166 }
167
168 #[must_use]
170 pub fn build(self) -> Task<Args, Ctx, IdType> {
171 let current_time = || {
172 SystemTime::now()
173 .duration_since(UNIX_EPOCH)
174 .expect("Time went backwards")
175 .as_secs()
176 };
177
178 Task {
179 args: self.args,
180 parts: Parts {
181 task_id: self.task_id,
182 data: self.data,
183 attempt: self.attempt.unwrap_or_default(),
184 ctx: self.ctx,
185 status: self.status.unwrap_or(Status::Pending).into(),
186 run_at: self.run_at.unwrap_or_else(current_time),
187 },
188 }
189 }
190}
191
192impl<Args, Ctx: Default, IdType> Task<Args, Ctx, IdType> {
194 pub fn builder(args: Args) -> TaskBuilder<Args, Ctx, IdType> {
196 TaskBuilder::new(args)
197 }
198}