pub trait PeriodicBackgroundService:
Send
+ Sync
+ 'static {
// Required methods
fn interval(&self) -> Duration;
fn tick<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait;
// Provided method
fn stop_on_error(&self) -> bool { ... }
}Expand description
A periodic worker: the framework owns the interval loop, the interruptible
wait and stop/join; business code implements tick
only.
This is the extracted form of the hand-rolled
AtomicBool + Notify + Mutex<JoinHandle> runner every application used to
duplicate (interval, wake-on-stop, join, “tick already running finishes”
semantics). Implement it, register it with add_background_service*, and
you get a cancellable timer for free:
struct OutboxWorker { services: Arc<dyn ScopeFactory>, interval: Duration }
#[async_trait]
impl PeriodicBackgroundService for OutboxWorker {
fn interval(&self) -> Duration { self.interval }
async fn tick(&self) -> Result<()> {
let scope = self.services.create_scope(); // one scope per tick
publish_due(&scope).await
}
}Semantics (kept identical to the runner this replaces):
- the first tick runs after one interval;
- a tick that is already running finishes before the loop stops — keep ticks short/bounded;
- a failed tick is logged and the next one runs on schedule, unless
stop_on_erroristrue; - shutdown interrupts the wait immediately, so a 60s interval never delays a 30s shutdown window.
It is automatically a BackgroundService, so
add_background_service_with / add_background_service accept it as-is.
Required Methods§
Provided Methods§
Sourcefn stop_on_error(&self) -> bool
fn stop_on_error(&self) -> bool
Whether a failed tick stops the worker.
Defaults to false: a poller must survive a transient database outage.
Return true for work where a failure is fatal (the error then ends
execute and is reported from stop()).
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".