Novel, Safe Uses for sync::Weak?

⚓ Rust    📅 2026-06-24    👤 surdeus    👁️ 2      

surdeus

I had a thought about trying to optimize long-lived values that exist in an Arc<T> and wanted to see if these novel uses make sense with what sync::Weak<T> is designed to do.

The docs give an example of using Weak<T> for graphs for a node that needs to reference its parent.

I had an idea for more uses for Weak<T> and wanted to understand if it is sufficient/appropriate.

Example: Web Server

Here is the example and documentation that axum provides for sharing state:

use axum::{
   extract::State,
   routing::get,
   Router,
};
use std::sync::Arc;

struct AppState {
   // ...
}

let shared_state = Arc::new(AppState { /* ... */ });

let app = Router::new()
   .route("/", get(handler))
   .with_state(shared_state);

async fn handler(
    State(state): State<Arc<AppState>>,
) {
    // ...
}

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 is itself an Arc or a copy type), you can #[derive(Clone)] directly on the struct instead.

For the sake of my question, I'm going to assume that the following invariant is upheld, that no handler execution shall outlive the axum::Router itself. I am aware that this might be impossible because I could tokio::spawn or spawn a new thread within a handler to escape this, but I'm going to pretend it is true. I'm also not particularly concerned here in my example with the particulars of axum, it's just an example.

If such a guarantee were able to be made, would using Weak<T> references be safe and would remove the atomic increment/decrement on the Arc for every request? I'm aware that in this example we are I/O bound and atomic contention on the CPU is probably not at all affecting things, but I still want to understand if this is a safe way to eliminate this sort of +1/-1 on every handler execution.

4 posts - 4 participants

Read full topic

🏷️ Rust_feed