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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
use graphile_worker_task_handler::{BatchTaskHandler, JobDefinition, TaskHandler};
use super::WorkerOptions;
impl WorkerOptions {
/// Restricts this worker to jobs whose every flag key is listed.
///
/// This rejects newly introduced or unknown labels without enumerating
/// exclusions. Include operational labels such as `infrastructure_resilient`.
/// Keys match exactly and case-sensitively. An empty list admits only untagged
/// jobs for this predicate; accepted routing and forbidden vetoes still apply.
/// By default no allowlist restriction is added. LocalQueue filters before
/// claiming batches. Other workers remain governed by their own configuration.
/// Calling this method again replaces the previously configured allowlist.
///
/// ```
/// use graphile_worker::WorkerOptions;
/// let options = WorkerOptions::default()
/// .job_flag_allowlist(["amd-linux", "kvm", "fast-disk"])
/// .add_accepted_flag("fast-disk");
/// ```
pub fn job_flag_allowlist<I, S>(mut self, flags: I) -> Self
where
I: IntoIterator<Item = S>,
S: Into<String>,
{
self.job_flag_allowlist = Some(flags.into_iter().map(Into::into).collect());
self
}
/// Adds a positive job-routing label.
///
/// With at least one accepted flag, a job must carry any accepted flag.
/// Jobs without a matching label are excluded; forbidden flags always veto.
/// With no accepted flags, positive filtering is disabled. This selects
/// labels, not worker capabilities. LocalQueue applies the same filter to batches.
pub fn add_accepted_flag(mut self, flag: &str) -> Self {
self.accepted_flags.push(flag.into());
self
}
/// Registers a task handler type with the worker.
///
/// Primary way to define what types of jobs this worker can process.
/// Each task handler implements the `TaskHandler` trait, which defines how to
/// deserialize and run jobs of a specific type.
///
/// # Type Parameters
/// * `T` - A type implementing the TaskHandler trait
///
/// # Example
/// ```
/// # use graphile_worker::{WorkerOptions, TaskHandler, WorkerContext, IntoTaskHandlerResult};
/// # use serde::{Deserialize, Serialize};
/// #
/// # #[derive(Deserialize, Serialize)]
/// # struct SendEmail { to: String }
/// #
/// # impl TaskHandler for SendEmail {
/// # const IDENTIFIER: &'static str = "send_email";
/// # async fn run(self, _ctx: WorkerContext) -> impl IntoTaskHandlerResult {
/// # Ok::<(), String>(())
/// # }
/// # }
///
/// let options = WorkerOptions::default()
/// .define_job::<SendEmail>();
/// ```
pub fn define_job<T: TaskHandler>(self) -> Self {
self.define_jobs([T::definition()])
}
/// Registers a batch task handler type with the worker.
///
/// Batch handlers receive a vector of item payloads from a single JSON-array
/// job payload and may return per-item results so successful items are not
/// retried after partial failure.
pub fn define_batch_job<T: BatchTaskHandler>(self) -> Self {
self.define_jobs([T::definition()])
}
/// Registers task handler definitions with the worker.
///
/// This is useful when a module or crate exposes the jobs it can process as
/// reusable values.
///
/// # Arguments
/// * `jobs` - Job definitions created with [`TaskHandler::definition`] or
/// [`JobDefinition::of`]
///
/// # Example
/// ```
/// # use graphile_worker::{
/// # IntoTaskHandlerResult, JobDefinition, TaskHandler, WorkerContext, WorkerOptions,
/// # };
/// # use serde::{Deserialize, Serialize};
/// #
/// # #[derive(Deserialize, Serialize)]
/// # struct SendEmail;
/// #
/// # impl TaskHandler for SendEmail {
/// # const IDENTIFIER: &'static str = "send_email";
/// # async fn run(self, _ctx: WorkerContext) -> impl IntoTaskHandlerResult {}
/// # }
/// #
/// fn jobs() -> [JobDefinition; 1] {
/// [SendEmail::definition()]
/// }
///
/// let options = WorkerOptions::default()
/// .define_jobs(jobs());
/// ```
pub fn define_jobs<I>(mut self, jobs: I) -> Self
where
I: IntoIterator<Item = JobDefinition>,
{
for job in jobs {
let (identifier, worker_fn) = job.into_parts();
self.jobs.insert(identifier.to_string(), worker_fn);
}
self
}
/// Adds a flag to the list of forbidden flags.
///
/// Jobs with any forbidden flag will be skipped by this worker instance.
/// Can be used to implement specialized workers that only handle
/// certain types of jobs.
///
/// # Arguments
/// * `flag` - The flag to forbid
///
/// # Example
/// ```
/// # use graphile_worker::WorkerOptions;
///
/// // This worker will skip jobs with the "high_memory" flag
/// let options = WorkerOptions::default()
/// .add_forbidden_flag("high_memory");
/// ```
pub fn add_forbidden_flag(mut self, flag: &str) -> Self {
self.forbidden_flags.push(flag.into());
self
}
}