Skip to main content

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}