graphile_worker/builder/hooks.rs
1use std::fmt::Debug;
2
3use graphile_worker_lifecycle_hooks::{Event, Plugin};
4
5use super::WorkerOptions;
6
7impl WorkerOptions {
8 /// Adds a custom extension to the worker context.
9 ///
10 /// Extensions provide custom application state or dependencies
11 /// that are accessible from task handlers. Useful for sharing resources
12 /// like API clients, configuration, or other state between jobs.
13 ///
14 /// # Type Parameters
15 /// * `T` - Type of the extension (must be Clone, Send, Sync, Debug, and 'static)
16 ///
17 /// # Arguments
18 /// * `value` - The extension instance to add
19 ///
20 /// # Example
21 /// ```
22 /// # use graphile_worker::WorkerOptions;
23 /// # use std::sync::Arc;
24 /// #
25 /// # #[derive(Clone, Debug)]
26 /// # struct AppConfig {
27 /// # api_key: String,
28 /// # }
29 /// #
30 /// # #[derive(Clone, Debug)]
31 /// # struct Database {
32 /// # // Database connection or client
33 /// # }
34 ///
35 /// let config = AppConfig {
36 /// api_key: "secret".to_string(),
37 /// };
38 ///
39 /// let db = Database {
40 /// // Initialize database
41 /// };
42 ///
43 /// let options = WorkerOptions::default()
44 /// .add_extension(config)
45 /// .add_extension(db);
46 /// ```
47 pub fn add_extension<T: Clone + Send + Sync + Debug + 'static>(mut self, value: T) -> Self {
48 self.extensions.insert(value);
49 self
50 }
51
52 /// Registers an event handler for a specific lifecycle event.
53 ///
54 /// This method allows registering individual handlers for specific events
55 /// without creating a full plugin. The handler is a closure that receives
56 /// the event context and returns the appropriate output type.
57 ///
58 /// # Type Parameters
59 /// * `E` - The event type to handle
60 ///
61 /// # Arguments
62 /// * `event` - The event marker (e.g., `JobStart`, `BeforeJobRun`)
63 /// * `handler` - The async handler closure
64 ///
65 /// # Example
66 /// ```ignore
67 /// use graphile_worker::{WorkerOptions, JobStart, BeforeJobRun, HookResult};
68 ///
69 /// let options = WorkerOptions::default()
70 /// .on(JobStart, |ctx| async move {
71 /// println!("Job {} starting", ctx.job.id());
72 /// })
73 /// .on(BeforeJobRun, |ctx| async move {
74 /// if ctx.payload.get("skip").and_then(|v| v.as_bool()).unwrap_or(false) {
75 /// return HookResult::Skip;
76 /// }
77 /// HookResult::Continue
78 /// });
79 /// ```
80 pub fn on<E, F, Fut>(mut self, event: E, handler: F) -> Self
81 where
82 E: Event,
83 F: Fn(E::Context) -> Fut + Send + Sync + Clone + 'static,
84 Fut: std::future::Future<Output = E::Output> + Send + 'static,
85 {
86 self.hooks.on(event, handler);
87 self
88 }
89
90 /// Adds a lifecycle hook plugin to the worker.
91 ///
92 /// Plugins can observe and intercept various worker events such as
93 /// job execution, worker startup/shutdown, and cron scheduling.
94 /// Multiple plugins can be registered and they execute in registration order.
95 ///
96 /// # Type Parameters
97 /// * `P` - A type implementing the Plugin trait
98 ///
99 /// # Arguments
100 /// * `plugin` - The plugin instance to add
101 ///
102 /// # Example
103 /// ```ignore
104 /// use graphile_worker::{WorkerOptions, Plugin, HookRegistry, JobStart};
105 ///
106 /// struct LoggingPlugin;
107 ///
108 /// impl Plugin for LoggingPlugin {
109 /// fn register(self, hooks: &mut HookRegistry) {
110 /// hooks.on::<JobStart>(|ctx| async move {
111 /// println!("Job {} starting", ctx.job.id());
112 /// });
113 /// }
114 /// }
115 ///
116 /// let options = WorkerOptions::default()
117 /// .add_plugin(LoggingPlugin);
118 /// ```
119 pub fn add_plugin<P: Plugin>(mut self, plugin: P) -> Self {
120 plugin.register(&mut self.hooks);
121 self
122 }
123}