mirror of
https://github.com/tokio-rs/axum.git
synced 2026-09-07 00:00:12 +02:00
axum: add docs describing how, why and when to use &'static state (#3838)
This commit is contained in:
+70
-1
@@ -186,7 +186,76 @@
|
|||||||
//! State is cloned for every request. Wrapping your state in `Arc` makes those
|
//! State is cloned for every request. Wrapping your state in `Arc` makes those
|
||||||
//! clones cheap. If all fields are already cheap to clone (for example, each field
|
//! clones cheap. If all fields are already cheap to clone (for example, each field
|
||||||
//! is itself an `Arc` or a copy type), you can `#[derive(Clone)]` directly on the
|
//! is itself an `Arc` or a copy type), you can `#[derive(Clone)]` directly on the
|
||||||
//! struct instead.
|
//! struct instead. Many client types, such as [`reqwest::Client`], AWS SDK service
|
||||||
|
//! clients, and [`mongodb::Client`], already use shared ownership internally and
|
||||||
|
//! are cheap to clone. Such clients generally do not need another `Arc` solely to
|
||||||
|
//! make cloning cheap; doing so adds another level of indirection.
|
||||||
|
//!
|
||||||
|
//! [`reqwest::Client`]: https://docs.rs/reqwest/latest/reqwest/struct.Client.html
|
||||||
|
//! [`mongodb::Client`]: https://docs.rs/mongodb/latest/mongodb/struct.Client.html
|
||||||
|
//!
|
||||||
|
//! ### Using `&'static` state
|
||||||
|
//!
|
||||||
|
//! For state built once and intended to live until the process exits, [`Box::leak`]
|
||||||
|
//! or a static [`LazyLock`] can provide a `&'static AppState` to the router. Use
|
||||||
|
//! `Box::leak` for state initialized in `main`, including when state initialization
|
||||||
|
//! requires asynchronous work; use a static `LazyLock` for global state with a
|
||||||
|
//! synchronous lazy initializer. This is useful for state built from runtime
|
||||||
|
//! configuration, database pools, or service clients:
|
||||||
|
//!
|
||||||
|
//! ```rust
|
||||||
|
//! use axum::{
|
||||||
|
//! extract::State,
|
||||||
|
//! routing::get,
|
||||||
|
//! Router,
|
||||||
|
//! };
|
||||||
|
//!
|
||||||
|
//! struct AppState {
|
||||||
|
//! // A database pool, service clients, configuration, etc.
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! impl AppState {
|
||||||
|
//! async fn work(&self) {}
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! fn main() {
|
||||||
|
//! let app_state = AppState {
|
||||||
|
//! // Initialize fields at startup.
|
||||||
|
//! };
|
||||||
|
//! let app_state: &'static AppState = Box::leak(Box::new(app_state));
|
||||||
|
//!
|
||||||
|
//! let app = Router::new()
|
||||||
|
//! .route("/", get(handler))
|
||||||
|
//! .with_state(app_state);
|
||||||
|
//! # let _: Router = app;
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! async fn handler(State(state): State<&'static AppState>) {
|
||||||
|
//! let _task = tokio::spawn(async move {
|
||||||
|
//! state.work().await;
|
||||||
|
//! });
|
||||||
|
//!
|
||||||
|
//! // `state` is still available in the handler because it was copied.
|
||||||
|
//! state.work().await;
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! Like every shared reference, a `&'static T` is `Copy`, so axum can clone it for
|
||||||
|
//! each request without an atomic reference-count operation. This can be cheaper than
|
||||||
|
//! cloning an `Arc`, but it is rarely a reason on its own to choose process-lifetime
|
||||||
|
//! state since the request's actual work normally matters more. The more practical
|
||||||
|
//! advantage of combining `Copy` with the `'static` lifetime is shown above: an
|
||||||
|
//! `async move` block copies the reference into the spawned Tokio task while leaving
|
||||||
|
//! the handler's copy available. With `Arc`, call [`Arc::clone`] before spawning when
|
||||||
|
//! the handler also needs the state.
|
||||||
|
//!
|
||||||
|
//! `Box::leak` deliberately leaks its allocation, and state held by a static
|
||||||
|
//! `LazyLock` is likewise never dropped. Use either only for process-lifetime state.
|
||||||
|
//! Use `Arc` when the state needs a managed lifetime.
|
||||||
|
//!
|
||||||
|
//! [`Arc::clone`]: https://doc.rust-lang.org/std/sync/struct.Arc.html#method.clone
|
||||||
|
//! [`Box::leak`]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.leak
|
||||||
|
//! [`LazyLock`]: https://doc.rust-lang.org/std/sync/struct.LazyLock.html
|
||||||
//!
|
//!
|
||||||
//! ### Substates with `FromRef`
|
//! ### Substates with `FromRef`
|
||||||
//!
|
//!
|
||||||
|
|||||||
Reference in New Issue
Block a user