apalis_core/worker/service.rs
1//! Worker service composition and task-function validation utilities.
2//!
3//! This module provides the types and traits used to combine a [`Backend`]
4//! with a task-processing service. It also contains utilities for validating
5//! task function signatures when the `test-utils` feature is enabled.
6
7use tower_service::Service;
8
9use crate::backend::Backend;
10
11/// A worker service composed of a backend and a task-processing service.
12///
13/// `WorkerService` combines the [`Backend`] responsible for retrieving and
14/// managing tasks with the [`Service`] responsible for processing them.
15#[derive(Debug, Clone)]
16pub struct WorkerService<Backend, Svc> {
17 /// The backend used by the worker.
18 pub backend: Backend,
19
20 /// The service used to process tasks.
21 pub service: Svc,
22}
23
24/// A trait for constructing a [`WorkerService`] from a backend.
25///
26/// Implementations define how a service is combined with a backend before
27/// being passed to a worker.
28///
29/// # Type Parameters
30///
31/// * `B` - The backend supplied when constructing the worker service.
32/// * `Svc` - The service used to process tasks.
33///
34/// # Associated Types
35///
36/// * [`Task`](Self::Task) - The task type processed by the worker.
37/// * [`Backend`](Self::Backend) - The backend used by the resulting worker
38/// service.
39pub trait IntoWorkerService<B, Svc>
40where
41 B: Backend,
42 Svc: Service<<Self::Backend as Backend>::Task>,
43{
44 /// The task type processed by the worker.
45 type Task;
46
47 /// The backend type used by the worker service.
48 type Backend: Backend<Task = Self::Task>;
49
50 /// Builds a worker service from the provided backend.
51 fn into_service(self, backend: B) -> WorkerService<Self::Backend, Svc>;
52}
53
54/// Utilities for validating task function implementations.
55///
56/// This module provides helper functions for checking that task functions
57/// conform to the signatures supported by worker services.
58///
59/// The module is available when the `test-utils` feature is enabled.
60#[cfg(feature = "test-utils")]
61pub mod task_fn_validator {
62 use crate::backend::Backend;
63 use crate::backend::BackendConfig;
64 use crate::task::Task;
65 use tower_service::Service;
66
67 use crate::task::from_request::FromRequest;
68 use crate::task::task_fn::TaskFn;
69
70 /// Macro for implementing the check functions
71 macro_rules! impl_check_fn {
72 ($($num:tt => $($arg:ident),+);+ $(;)?) => {
73 $(
74 #[inline]
75 #[doc = concat!("A helper for checking that the builder can build a worker with the provided service (", stringify!($num), " arguments)")]
76 pub fn $num<
77 F, B, Args,
78 $($arg: FromRequest<Task<Args>>),+
79 >(
80 _: F,
81 ) where
82 TaskFn<F, Args, ($($arg,)+)>: Service<Task<Args>>,
83 B: Backend + BackendConfig<Args = Args>
84 {
85 }
86 )+
87 };
88 }
89
90 impl_check_fn! {
91 check_fn_1 => A1;
92 check_fn_2 => A1, A2;
93 check_fn_3 => A1, A2, A3;
94 check_fn_4 => A1, A2, A3, A4;
95 check_fn_5 => A1, A2, A3, A4, A5;
96 check_fn_6 => A1, A2, A3, A4, A5, A6;
97 check_fn_7 => A1, A2, A3, A4, A5, A6, A7;
98 check_fn_8 => A1, A2, A3, A4, A5, A6, A7, A8;
99 check_fn_9 => A1, A2, A3, A4, A5, A6, A7, A8, A9;
100 check_fn_10 => A1, A2, A3, A4, A5, A6, A7, A8, A9, A10;
101 check_fn_11 => A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11;
102 check_fn_12 => A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12;
103 check_fn_13 => A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13;
104 check_fn_14 => A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14;
105 check_fn_15 => A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15;
106 check_fn_16 => A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16;
107 }
108}