Skip to main content

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}