Shared state in Rust
State carries a handle to whatever your handlers share — a pool, a cache, a counter.
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
use axum::extract::State;
use axum::{routing::get, Router};
#[derive(Clone)]
struct AppState {
hits: Arc<AtomicU64>,
}
async fn count(State(state): State<AppState>) -> String {
let n = state.hits.fetch_add(1, Ordering::Relaxed) + 1;
format!("{n} requests so far")
}
#[tokio::main]
async fn main() {
let state = AppState { hits: Arc::new(AtomicU64::new(0)) };
let app = Router::new().route("/count", get(count)).with_state(state);
let listener = tokio::net::TcpListener::bind("127.0.0.1:8080")
.await
.unwrap();
axum::serve(listener, app).await.unwrap();
}
How it works
with_stateattaches it to the router.State<T>extracts it in each handler.- The value is cloned per request, so wrap it in an
Arc.
Keywords and builtins used here
AppStateArcStateStringasyncawaitcountfnletmainstructuse
The run, in numbers
- Lines
- 26
- Characters to type
- 626
- Tokens
- 189
- Three-star pace
- 110 tpm
At the three-star pace of 110 tokens a minute, this run takes about 103 seconds.
Step 2 of 2 in Extractors & state, step 5 of 9 in Web services with axum.