Expand description
Process-wide lifecycle and listener composition for Baukit services.
This crate owns mechanics shared by an entire process: shutdown signaling, bounded draining, background-task supervision, build identity, and the thin composition of public and operations listeners. Products continue to own configuration, routes, and application state.
§Composition example
A composition root can wire the crate to baukit-config and
baukit-telemetry without making runtime own either product configuration or
telemetry policy:
use std::sync::Arc;
use axum::Router;
use baukit_runtime::{
ProcessKind, RestartPolicy, ServiceInfo, ShutdownToken, TaskSupervisor,
ShutdownOrder, build_info, serve_listener_pair_with_shutdown_order,
};
use baukit_telemetry::{DeploymentEnvironment, TelemetryBuilder};
use tokio::net::TcpListener;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let service = ServiceInfo::new(
"orders",
ProcessKind::Api,
build_info!(),
DeploymentEnvironment::Local,
);
let telemetry = Arc::new(
TelemetryBuilder::new(service.telemetry_identity().clone()).init()?,
);
let shutdown = ShutdownToken::new(Duration::from_secs(30));
let signal_task = shutdown.spawn_signal_listener();
let mut workers = TaskSupervisor::new(shutdown.clone());
let worker_shutdown = shutdown.child_token();
workers.spawn("outbox", RestartPolicy::Restart { max_restarts: 3 }, move || {
let worker_shutdown = worker_shutdown.clone();
async move { run_outbox_until(worker_shutdown).await }
});
let api = TcpListener::bind("127.0.0.1:0").await?;
let ops = TcpListener::bind("127.0.0.1:0").await?;
let listener_result = serve_listener_pair_with_shutdown_order(
api,
Router::new().merge(product_routes()),
ops,
Router::new().merge(operations_routes()),
shutdown.clone(),
ShutdownOrder::OpsOutlivesApi,
).await;
shutdown.trigger();
let _ = workers.join().await;
// Telemetry shutdown is synchronous, so keep it off the async executor.
// `run_during_drain` still bounds it by the process-wide drain deadline.
let telemetry_for_flush = Arc::clone(&telemetry);
shutdown.run_during_drain(async move {
tokio::task::spawn_blocking(move || telemetry_for_flush.shutdown()).await
}).await???;
signal_task.abort();
listener_result?;
Ok(())
}Macros§
- build_
info - Captures build metadata from the binary crate in which the macro is invoked.
Structs§
- Build
Info - Immutable version-control and compiler metadata for a process build.
- Drain
Timeout - Indicates that process draining exceeded its shared deadline.
- Service
Identity - Stable identity and build metadata for one running process.
- Service
Info - Canonical service identity plus its complete process build metadata.
- Shutdown
Token - A cloneable, awaitable process-shutdown handle with one shared drain deadline.
- Task
Supervisor - Owns named background tasks tied to one
ShutdownToken.
Enums§
- Deployment
Environment - The deployment environment attached to configuration and telemetry signals.
- Listener
Kind - Identifies one member of an API/operations listener pair.
- Listener
Pair Error - An error returned while running the API and operations listeners.
- Process
Kind - The kind of process being identified and instrumented.
- Restart
Policy - The response to a supervised task’s unexpected termination.
- Shutdown
Order - Controls when the operations listener stops relative to the public API.
- Shutdown
Signal - The operating-system event which initiated shutdown.
Constants§
- RUST_
VERSION - The Rust compiler version used to build this crate.
Functions§
- serve_
listener_ pair - Runs public API and operations routers concurrently with graceful shutdown.
- serve_
listener_ pair_ with_ shutdown_ order - Runs an API/operations listener pair with an explicit shutdown order.
- wait_
for_ shutdown_ signal - Waits for the first supported process shutdown signal without triggering a token.
Type Aliases§
- Shutdown
- A concise alias for
ShutdownToken.