libdd_shared_runtime/worker.rs
1// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/
2// SPDX-License-Identifier: Apache-2.0
3
4use async_trait::async_trait;
5use libdd_capabilities::MaybeSend;
6
7/// A background worker meant to be spawned on a [`SharedRuntime`](crate::SharedRuntime).
8///
9/// # Lifecycle
10/// The worker's [`run`](Self::run) method is executed every time [`trigger`](Self::trigger)
11/// returns. On startup [`initial_trigger`](Self::initial_trigger) is called before the first
12/// [`run`](Self::run).
13///
14/// # Cancellation safety
15/// The `trigger` function can be interrupted at any yield point (`.await`ed call). The state of the
16/// worker at this point will be saved and used to restart the worker. To be able to safely restart,
17/// the worker must be in a valid state on every call to `.await` within the trigger function.
18/// See [`tokio::select#cancellation-safety`] for more details.
19#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
20#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
21pub trait Worker: std::fmt::Debug + MaybeSend {
22 /// Main worker function
23 ///
24 /// Code in this function must always use timeout on long-running await calls to avoid
25 /// blocking forks if an await call takes too long to complete.
26 async fn run(&mut self);
27
28 /// Function called between each `run` to wait for the next run.
29 /// This function should be cancellation safe as it can be cancelled at any yield point.
30 async fn trigger(&mut self);
31
32 /// Alternative trigger called on start to provide custom behavior.
33 /// Defaults to `trigger` behavior.
34 async fn initial_trigger(&mut self) {
35 self.trigger().await
36 }
37
38 /// Reset the worker state. Called in the child after a fork to cleanup parent state.
39 fn reset(&mut self) {}
40
41 /// Hook called when the app is shutting down. Can be used to flush remaining data.
42 async fn shutdown(&mut self) {}
43}
44
45// Blanket implementation for boxed trait objects
46#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
47#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
48impl Worker for Box<dyn Worker + Sync> {
49 async fn run(&mut self) {
50 (**self).run().await
51 }
52
53 async fn trigger(&mut self) {
54 (**self).trigger().await
55 }
56
57 async fn initial_trigger(&mut self) {
58 (**self).initial_trigger().await
59 }
60
61 fn reset(&mut self) {
62 (**self).reset()
63 }
64
65 async fn shutdown(&mut self) {
66 (**self).shutdown().await
67 }
68}