From 1f224396a2e7ddfbd6815a47311769775de08624 Mon Sep 17 00:00:00 2001 From: Hugh Mandalidis Date: Thu, 23 Feb 2023 23:44:25 +1100 Subject: [PATCH] Add shared mutable state documentation (#1759) Co-authored-by: Vagelis Prokopiou Co-authored-by: Jonas Platte Co-authored-by: David Pedersen --- axum/src/extract/state.rs | 43 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/axum/src/extract/state.rs b/axum/src/extract/state.rs index 447935d8..2de9f868 100644 --- a/axum/src/extract/state.rs +++ b/axum/src/extract/state.rs @@ -295,6 +295,49 @@ use std::{ /// /// In general however we recommend you implement `Clone` for all your state types to avoid /// potential type errors. +/// +/// # Shared mutable state +/// +/// [As state is global within a `Router`][global] you can't directly get a mutable reference to +/// the state. +/// +/// The most basic solution is to use an `Arc>`. Which kind of mutex you need depends on +/// your use case. See [the tokio docs] for more details. +/// +/// Note that holding a locked `std::sync::Mutex` across `.await` points will result in `!Send` +/// futures which are incompatible with axum. If you need to hold a mutex across `.await` points, +/// consider using a `tokio::sync::Mutex` instead. +/// +/// ## Example +/// +/// ``` +/// use axum::{Router, routing::get, extract::State}; +/// use std::sync::{Arc, Mutex}; +/// +/// #[derive(Clone)] +/// struct AppState { +/// data: Arc>, +/// } +/// +/// async fn handler(State(state): State) { +/// let mut data = state.data.lock().expect("mutex was poisoned"); +/// *data = "updated foo".to_owned(); +/// +/// // ... +/// } +/// +/// let state = AppState { +/// data: Arc::new(Mutex::new("foo".to_owned())), +/// }; +/// +/// let app = Router::new() +/// .route("/", get(handler)) +/// .with_state(state); +/// # let _: Router = app; +/// ``` +/// +/// [global]: crate::Router::with_state +/// [the tokio docs]: https://docs.rs/tokio/1.25.0/tokio/sync/struct.Mutex.html#which-kind-of-mutex-should-you-use #[derive(Debug, Default, Clone, Copy)] pub struct State(pub S);