Skip to main content

apalis_core/backend/impls/
mod.rs

1use std::{
2    task::{Context, Poll},
3    time::Duration,
4};
5
6use futures_core::stream::BoxStream;
7use futures_util::StreamExt;
8use tower_layer::Identity;
9
10use crate::{
11    backend::{
12        Backend, BackendConfig, FetchById, Filter, ListAllTasks, ListQueues, ListTasks,
13        ListWorkers, Metrics, QueueInfo, RegisterWorker, Reschedule, ResumeAbandoned, ResumeById,
14        RunningWorker, Statistic, TaskResult, Update, Vacuum, WaitForCompletion, WireFormatBackend,
15        finalize::Ephemeral,
16    },
17    task::{
18        Task,
19        builder::TaskBuilder,
20        task_id::{RandomId, TaskId},
21    },
22    worker::context::WorkerContext,
23};
24
25/// Backend implementation based on VecDeque
26pub(crate) mod dequeue;
27/// In-memory backend implementation
28pub(crate) mod memory;
29
30// A boxed stream of tasks that implements the `Backend` trait
31impl<T, E> Backend for BoxStream<'_, Result<T, E>>
32where
33    E: std::error::Error + Send + Sync + 'static,
34{
35    type Task = Task<T>;
36
37    type Error = E;
38
39    fn poll_ready(
40        &mut self,
41        _cx: &mut Context<'_>,
42        _worker: &WorkerContext,
43    ) -> Poll<Result<(), Self::Error>> {
44        Poll::Ready(Ok(()))
45    }
46
47    fn poll_next(
48        &mut self,
49        cx: &mut Context<'_>,
50        _worker: &WorkerContext,
51    ) -> Poll<Option<Result<Self::Task, Self::Error>>> {
52        self.poll_next_unpin(cx).map_ok(|t| {
53            TaskBuilder::new(t)
54                .task_id(TaskId::from_string(RandomId::default()))
55                .build()
56        })
57    }
58
59    fn poll_close(
60        &mut self,
61        _cx: &mut Context<'_>,
62        _worker: &WorkerContext,
63    ) -> Poll<Result<(), Self::Error>> {
64        Poll::Ready(Ok(()))
65    }
66}
67
68impl<T, E> BackendConfig for BoxStream<'_, Result<T, E>>
69where
70    E: std::error::Error + Send + Sync + 'static,
71{
72    type Args = T;
73    type Kind = Ephemeral;
74
75    type Id = RandomId;
76
77    type Config = ();
78
79    type Layer = Identity;
80
81    fn config(&self) -> &Self::Config {
82        &()
83    }
84
85    fn middleware(&mut self, _worker: &mut WorkerContext) -> Self::Layer {
86        Identity::new()
87    }
88}
89
90impl<B: Backend> Backend for &mut B {
91    type Task = B::Task;
92
93    type Error = B::Error;
94
95    fn poll_ready(
96        &mut self,
97        cx: &mut Context<'_>,
98        worker: &WorkerContext,
99    ) -> Poll<Result<(), Self::Error>> {
100        (**self).poll_ready(cx, worker)
101    }
102
103    fn poll_next(
104        &mut self,
105        cx: &mut Context<'_>,
106        worker: &WorkerContext,
107    ) -> Poll<Option<Result<Self::Task, Self::Error>>> {
108        (**self).poll_next(cx, worker)
109    }
110
111    fn poll_close(
112        &mut self,
113        cx: &mut Context<'_>,
114        worker: &WorkerContext,
115    ) -> Poll<Result<(), Self::Error>> {
116        (**self).poll_close(cx, worker)
117    }
118}
119
120impl<B: BackendConfig> BackendConfig for &mut B {
121    type Args = B::Args;
122    type Kind = B::Kind;
123
124    type Id = B::Id;
125
126    type Config = B::Config;
127
128    type Layer = B::Layer;
129
130    fn config(&self) -> &Self::Config {
131        BackendConfig::config(*self)
132    }
133
134    fn middleware(&mut self, worker: &mut WorkerContext) -> Self::Layer {
135        BackendConfig::middleware(*self, worker)
136    }
137}
138
139impl<B: WireFormatBackend> WireFormatBackend for &mut B {
140    type Codec = B::Codec;
141
142    type Compact = B::Compact;
143
144    fn codec(&self) -> &Self::Codec {
145        WireFormatBackend::codec(*self)
146    }
147}
148
149impl<B> FetchById for &mut B
150where
151    B: FetchById,
152    B::Task: Send,
153    B: Backend + Send,
154{
155    async fn fetch_by_id(
156        &mut self,
157        task_id: &crate::task::task_id::TaskId,
158    ) -> Result<Option<B::Task>, Self::Error> {
159        <B as FetchById>::fetch_by_id(*self, task_id).await
160    }
161}
162impl<B> Update for &mut B
163where
164    B: Update + Send,
165    B::Task: Send,
166    B: Backend + Send,
167{
168    async fn update(&mut self, task: Self::Task) -> Result<(), Self::Error> {
169        <B as Update>::update(*self, task).await
170    }
171}
172impl<B> Reschedule for &mut B
173where
174    B: Reschedule,
175    B::Task: Send,
176    B: Backend + Send,
177{
178    async fn reschedule(
179        &mut self,
180        task: Self::Task,
181        wait: std::time::Duration,
182    ) -> Result<(), Self::Error> {
183        <B as Reschedule>::reschedule(*self, task, wait).await
184    }
185}
186impl<B> Vacuum for &mut B
187where
188    B: Vacuum,
189    B: Backend + Send,
190{
191    async fn vacuum(&mut self) -> Result<usize, Self::Error> {
192        <B as Vacuum>::vacuum(*self).await
193    }
194    async fn vacuum_before(&mut self, duration: Duration) -> Result<usize, Self::Error> {
195        <B as Vacuum>::vacuum_before(*self, duration).await
196    }
197}
198impl<B> ResumeById for &mut B
199where
200    B: ResumeById,
201    B: Backend + Send,
202{
203    async fn resume_by_id(&mut self, id: TaskId) -> Result<bool, Self::Error> {
204        <B as ResumeById>::resume_by_id(*self, id).await
205    }
206}
207impl<B> ResumeAbandoned for &mut B
208where
209    B: ResumeAbandoned,
210    B: Backend + Send,
211{
212    async fn resume_abandoned(&mut self) -> Result<usize, Self::Error> {
213        <B as ResumeAbandoned>::resume_abandoned(*self).await
214    }
215}
216impl<B> RegisterWorker for &mut B
217where
218    B: RegisterWorker,
219    B: Backend + Send,
220{
221    async fn register_worker(&mut self, worker_id: String) -> Result<(), Self::Error> {
222        <B as RegisterWorker>::register_worker(*self, worker_id).await
223    }
224}
225impl<Output, B> WaitForCompletion<Output> for &mut B
226where
227    B: WaitForCompletion<Output> + Sync,
228    Output: 'static,
229    B: Backend + Send,
230{
231    type ResultStream = BoxStream<'static, Result<TaskResult<Output>, Self::Error>>;
232    fn wait_for(&mut self, task_ids: impl IntoIterator<Item = TaskId>) -> Self::ResultStream {
233        use futures_util::StreamExt;
234        let result = <B as WaitForCompletion<Output>>::wait_for(*self, task_ids);
235        result.boxed()
236    }
237    async fn check_status(
238        &mut self,
239        task_ids: impl IntoIterator<Item = TaskId> + Send,
240    ) -> Result<Vec<TaskResult<Output>>, Self::Error> {
241        <B as WaitForCompletion<Output>>::check_status(*self, task_ids).await
242    }
243}
244impl<B> ListQueues for &mut B
245where
246    B: ListQueues + Send + Sync,
247    B: Backend + Send,
248{
249    async fn list_queues(&self) -> Result<Vec<QueueInfo>, Self::Error> {
250        <B as ListQueues>::list_queues(*self).await
251    }
252}
253impl<B> ListWorkers for &mut B
254where
255    B: ListWorkers + Send + Sync,
256    B: Backend + Send,
257{
258    async fn list_workers(&self) -> Result<Vec<RunningWorker>, Self::Error> {
259        <B as ListWorkers>::list_workers(*self).await
260    }
261    async fn list_all_workers(&self) -> Result<Vec<RunningWorker>, Self::Error> {
262        <B as ListWorkers>::list_all_workers(*self).await
263    }
264}
265impl<B> ListTasks for &mut B
266where
267    B: ListTasks + Send + Sync,
268    B: Backend + Send,
269{
270    async fn list_tasks(&self, filter: &Filter) -> Result<Vec<Task<Self::Compact>>, Self::Error> {
271        <B as ListTasks>::list_tasks(*self, filter).await
272    }
273}
274impl<B> ListAllTasks for &mut B
275where
276    B: ListAllTasks + Send + Sync,
277    B: Backend + Send,
278{
279    async fn list_all_tasks(
280        &self,
281        filter: &Filter,
282    ) -> Result<Vec<Task<Self::Compact>>, Self::Error> {
283        <B as ListAllTasks>::list_all_tasks(*self, filter).await
284    }
285}
286impl<B> Metrics for &mut B
287where
288    B: Metrics + Send + Sync,
289    B: Backend + Send,
290{
291    async fn global(&self) -> Result<Vec<Statistic>, Self::Error> {
292        <B as Metrics>::global(*self).await
293    }
294    async fn fetch_by_queue(&self) -> Result<Vec<Statistic>, Self::Error> {
295        <B as Metrics>::fetch_by_queue(*self).await
296    }
297}