pub trait IHostedService: Send + Sync {
// Required method
fn start<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait;
// Provided methods
fn stop<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait { ... }
fn order(&self) -> i32 { ... }
}Expand description
Background service that is started when the host starts and stopped when the host performs a graceful shutdown.
Analogous to ASP.NET Core’s IHostedService.
Use this for:
- Data initialization / seeding at application startup
- Background polling loops
- Queue consumers
- Connection pool warmup
§Example
#[derive(Default)]
struct DbInitService;
#[async_trait]
impl IHostedService for DbInitService {
async fn start(&self) -> Result<()> {
tracing::info!("[DbInitService] Running migrations...");
run_migrations().await?;
tracing::info!("[DbInitService] Seeding data...");
seed_data().await?;
Ok(())
}
async fn stop(&self) -> Result<()> {
tracing::info!("[DbInitService] Shutting down...");
Ok(())
}
}Required Methods§
Sourcefn start<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn start<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Called when the host starts.
Services start in registration order (after sorting by order)
and the host waits for all of them
before accepting requests. There is no ambient DI context: a hosted
service that needs scoped dependencies (DbContext, transactions, …)
takes rust-dix’s built-in #[inject] services: Arc<dyn ScopeFactory>
field and opens its own scope
(let scope = services.create_scope();), disposed with the scope.
If one start() fails, the services that already started are stopped
again in reverse order before the host reports the error.
Provided Methods§
Sourcefn stop<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn stop<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Called during a graceful shutdown.
The host stops the services that started, in reverse start order
(the last dependency to start is the first to stop), with a timeout per
service so one stuck service cannot block the process forever. Like
start(), each stop() runs inside a fresh DI scope.
Shutdown stops hosted services before in-flight connections are drained, so a worker never keeps running against services that are about to be torn down.
Sourcefn order(&self) -> i32
fn order(&self) -> i32
Start/stop priority. Lower starts first and stops last.
Defaults to 0; services with equal order keep their registration
order (the sort is stable). Use it when a dependency must be ready
before another: a migration/seed service at -100, cache warmup at 0,
queue consumers at 100.
Register with order through add_hosted_service_ordered /
add_hosted_service_with_ordered; the default keeps the historical
registration-order behavior.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".