Skip to main content

AppShutdown

Trait AppShutdown 

Source
pub trait AppShutdown {
    // Required method
    fn on_shutdown(&self) -> impl Future<Output = ()> + Send;
}
Expand description

Application cleanup that must finish before the process exits.

WebServer::run requires it of every state it carries, so a project cannot add app state and quietly forget that it needs draining. A server with no state gets the no-op implementation below and writes nothing.

The library owns the sequencing. This runs the moment the shutdown signal arrives, concurrently with the connection drain and under the same DEFAULT_DRAIN_TIMEOUT, so a slow drain never eats the cleanup’s budget and the two together cannot exceed one window. Overrunning is reported at error! by the caller — do not try to bound this yourself for that reason.

Being cut off at the ceiling is ordinary cancellation: the future is dropped at its last await point. Anything that must not be interrupted mid-way needs to be atomic on its own, because no shutdown design can cancel a synchronously blocking call.

§Idempotency

This runs once per server holding the state, so it must be idempotent. A binary running several servers off one Arc<AppState> calls it once per server. The library cannot deduplicate that — each WebServer builds its own WebServerState, and only the application knows what those share. Guard anything that would misbehave twice behind a OnceCell in your own state.

use std::future::Future;
use webserver_base::webserver::AppShutdown;

struct AppState {
    telegram: SomeNotifier,
}

impl AppShutdown for AppState {
    async fn on_shutdown(&self) {
        self.telegram.flush(std::time::Duration::from_secs(5)).await;
    }
}

Required Methods§

Source

fn on_shutdown(&self) -> impl Future<Output = ()> + Send

Drains whatever would otherwise be lost when the process exits.

Returns impl Future rather than being an async fn because the server’s own future must stay Send, and an async fn in a trait cannot promise that to its callers.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementations on Foreign Types§

Source§

impl AppShutdown for ()

A server carrying no application state has nothing to drain.

Deliberately the only blanket implementation: a project that adds state has to say what draining means for it, and that is the whole point of the bound.

Source§

async fn on_shutdown(&self)

Implementors§