Skip to main content

PeriodicBackgroundService

Trait PeriodicBackgroundService 

Source
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_error is true;
  • 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§

Source

fn interval(&self) -> Duration

How long to wait between ticks.

Must be greater than zero; a zero interval is a configuration error and fails the worker instead of spinning the CPU.

Source

fn tick<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, Self: 'async_trait,

One tick. Return Err to report a failure (logged, loop continues by default).

Provided Methods§

Source

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".

Implementors§