apalis_core/task/
builder.rs1use crate::{
28 backend::queue::Queue,
29 task::{
30 ExecutionContext, Task,
31 attempt::Attempt,
32 extensions::Extensions,
33 metadata::{Metadata, MetadataStore},
34 status::Status,
35 task_id::TaskId,
36 },
37};
38use std::{
39 fmt::Debug,
40 sync::Arc,
41 time::{Duration, SystemTime, UNIX_EPOCH},
42};
43
44#[derive(Debug)]
46#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
47#[must_use = "TaskBuilder is used to construct a Task. Ensure to call `.build()` to create the Task instance."]
48pub struct TaskBuilder<Args> {
49 pub(super) args: Args,
51 pub(super) ctx: ExecutionContext,
53}
54
55impl<Args> TaskBuilder<Args> {
56 pub fn new(args: Args) -> Self {
58 Self {
59 args,
60 ctx: ExecutionContext::default(),
61 }
62 }
63
64 pub fn with_metadata(mut self, metadata: MetadataStore) -> Self {
66 self.ctx.metadata = metadata;
67 self
68 }
69
70 pub fn with_data(mut self, data: Extensions) -> Self {
72 self.ctx.data = data;
73 self
74 }
75
76 pub fn data<D: Clone + Send + Sync + 'static>(mut self, value: D) -> Self {
78 self.ctx.data.insert(value);
79 self
80 }
81
82 pub fn metadata<M>(mut self, value: &M) -> Self
84 where
85 M: Metadata,
86 M::Error: Debug,
87 {
88 value
89 .inject(&mut self.ctx.metadata)
90 .expect("Could not add Metadata");
91 self
92 }
93
94 pub fn task_id(mut self, task_id: TaskId) -> Self {
96 self.ctx.task_id = Some(task_id);
97 self
98 }
99
100 pub fn attempt(mut self, attempt: usize) -> Self {
102 self.ctx.attempt = Attempt::new_with_value(attempt);
103 self
104 }
105
106 pub fn status(mut self, status: Status) -> Self {
108 self.ctx.status = status.into();
109 self
110 }
111
112 pub fn max_attempts(mut self, max_attempts: usize) -> Self {
114 self.ctx.max_attempts = Some(max_attempts);
115 self
116 }
117
118 pub fn priority(mut self, priority: usize) -> Self {
120 self.ctx.priority = Some(priority);
121 self
122 }
123
124 pub fn queue(mut self, queue: Queue) -> Self {
126 self.ctx.queue = Some(queue);
127 self
128 }
129
130 pub fn run_at_timestamp(mut self, timestamp: u64) -> Self {
132 self.ctx.run_at = Some(timestamp);
133 self
134 }
135
136 pub fn run_at_time(mut self, time: SystemTime) -> Self {
138 let timestamp = time
139 .duration_since(UNIX_EPOCH)
140 .expect("Time went backwards")
141 .as_secs();
142 self.ctx.run_at = Some(timestamp);
143 self
144 }
145
146 pub fn run_after(mut self, delay: Duration) -> Self {
148 let now = SystemTime::now();
149 let run_time = now + delay;
150 let timestamp = run_time
151 .duration_since(UNIX_EPOCH)
152 .expect("Time went backwards")
153 .as_secs();
154 self.ctx.run_at = Some(timestamp);
155 self
156 }
157
158 pub fn run_in_seconds(self, seconds: u64) -> Self {
160 self.run_after(Duration::from_secs(seconds))
161 }
162
163 pub fn run_in_minutes(self, minutes: u64) -> Self {
165 self.run_after(Duration::from_secs(minutes * 60))
166 }
167
168 pub fn run_in_hours(self, hours: u64) -> Self {
170 self.run_after(Duration::from_secs(hours * 3600))
171 }
172
173 pub fn idempotency_key<S: AsRef<str>>(mut self, idempotency_key: S) -> Self {
175 self.ctx.idempotency_key = Some(idempotency_key.as_ref().to_owned());
176 self
177 }
178
179 pub fn done_at(mut self, done_at: Option<u64>) -> Self {
181 self.ctx.done_at = done_at;
182 self
183 }
184
185 pub fn lock_at(mut self, lock_at: Option<u64>) -> Self {
187 self.ctx.lock_at = lock_at;
188 self
189 }
190
191 pub fn lock_by(mut self, lock_by: Option<String>) -> Self {
193 self.ctx.lock_by = lock_by;
194 self
195 }
196
197 pub fn build(self) -> Task<Args> {
199 Task {
200 args: self.args,
201 ctx: Arc::new(self.ctx),
202 }
203 }
204}
205
206impl<Args> TaskBuilder<Args> {
207 pub fn try_map_args<F, NewArgs, Err>(self, f: F) -> Result<TaskBuilder<NewArgs>, Err>
209 where
210 F: FnOnce(Args) -> Result<NewArgs, Err>,
211 {
212 Ok(TaskBuilder {
213 args: f(self.args)?,
214 ctx: self.ctx,
215 })
216 }
217 pub fn map_args<F, NewArgs>(self, f: F) -> TaskBuilder<NewArgs>
219 where
220 F: FnOnce(Args) -> NewArgs,
221 {
222 TaskBuilder {
223 args: f(self.args),
224 ctx: self.ctx,
225 }
226 }
227
228 pub fn map_context<F>(self, f: F) -> Self
230 where
231 F: FnOnce(ExecutionContext) -> ExecutionContext,
232 {
233 Self {
234 args: self.args,
235 ctx: f(self.ctx),
236 }
237 }
238}