Skip to main content

larust_core/lifecycle/
mod.rs

1//! Process lifecycle: graceful shutdown today, the dual-process
2//! zero-downtime restart handoff (listener passing, readiness protocol,
3//! admin restart channel) in later stages of the same feature.
4
5// `pub`, not `pub(crate)` on all three of these - needed so `lib.rs`'s
6// `#[doc(hidden)] pub mod __internal` can re-export them for this crate's
7// own fixture binaries and integration tests (which are separate crates
8// from this library, even though they share this package - see that
9// module's doc comment).
10pub mod admin;
11pub mod handoff;
12pub mod listener;
13pub(crate) mod readiness;
14mod signal;
15// Not re-exported via `__internal` like the four above -- only
16// `handoff.rs` ever calls into this; no fixture or external test needs
17// to reach it directly (see `supervisor`'s own doc comment).
18pub(crate) mod supervisor;
19
20pub(crate) use signal::wait_for_termination;
21
22use std::time::Duration;
23
24/// Configuration for [`crate::Application::with_graceful_shutdown`] -
25/// **opt-in**: an `Application` that never calls that method keeps today's
26/// exact behavior (a bare `axum::serve` that exits the instant Ctrl+C is
27/// pressed). Flipping every existing app's shutdown behavior silently
28/// would be exactly the kind of surprise a framework upgrade shouldn't
29/// introduce.
30#[derive(Debug, Clone)]
31pub struct GracefulShutdown {
32    /// Upper bound on how long `serve()` waits for in-flight requests to
33    /// finish after a shutdown signal, before forcing the process to exit
34    /// anyway. Never "wait forever" - a stuck connection (a slow client, a
35    /// hung upstream call) must not prevent a deploy or a plain Ctrl+C
36    /// from ever completing.
37    pub drain_timeout: Duration,
38    /// If `true`, also runs the local restart-trigger admin channel (see
39    /// `lifecycle::admin`) alongside plain Ctrl+C/SIGTERM handling - a
40    /// second, independent opt-in on top of graceful shutdown itself,
41    /// since not every app wants a local IPC surface open even when it
42    /// does want graceful shutdown. `false` by default. The binary to
43    /// spawn as a replacement is `std::env::current_exe()` for now (a
44    /// release-pointer convention, so a *newly built* binary rather than
45    /// the exact file currently running can be targeted, is a later
46    /// addition to this same feature).
47    pub restart_channel: bool,
48}
49
50impl Default for GracefulShutdown {
51    fn default() -> Self {
52        Self {
53            drain_timeout: Duration::from_secs(30),
54            restart_channel: false,
55        }
56    }
57}