Skip to main content

Module timeout

Module timeout 

Source
Expand description

Per-route request timeouts.

A single global read timeout (30 s per connection, or RWS_CONFIG_*) applies uniformly to every route today. A file-upload endpoint may legitimately need 120 s while a health check must complete in 500 ms — there’s no way to express that difference without wrapping a handler yourself. This module provides that wrapping.

§Honest limitation: Rust cannot preempt a running synchronous call

For synchronous handlers (Router, AppWithState, plain Applications), there is no safe way to forcibly stop a thread that’s already running. with_timeout, with_timeout_state, and TimeoutLayer all run the wrapped work on a background thread and bound how long they wait for it — if the deadline passes, the caller gets a 504 Gateway Timeout response immediately, but the background thread keeps running to completion (its result is simply discarded). This bounds the client’s wait time, not the handler’s actual resource usage.

For genuine cancellation, use with_timeout_async with AsyncAppWithState (requires the http2 feature): dropping a Future that hasn’t finished actually stops its execution at the next .await point, backed by tokio::time::timeout.

§Example — Router

use rust_web_server::router::Router;
use rust_web_server::timeout::with_timeout;
use rust_web_server::response::Response;
use rust_web_server::core::New;
use std::time::Duration;

let router = Router::new()
    .get("/healthz", with_timeout(Duration::from_millis(500), |_req, _params, _conn| Response::new()))
    .post("/upload", with_timeout(Duration::from_secs(120), |_req, _params, _conn| Response::new()));

§Example — wrapping a whole Application

use rust_web_server::app::App;
use rust_web_server::core::New;
use rust_web_server::timeout::TimeoutLayer;
use std::time::Duration;

let app = TimeoutLayer::new(App::new(), Duration::from_secs(5));

Structs§

TimeoutLayer
Wraps any owned Application (or a shared Arc<dyn Application>) so every request through it must complete within duration or the client gets 504 Gateway Timeout instead of waiting further.

Functions§

with_timeout
Wraps a stateless handler (the Router handler signature) so it must complete within duration or the caller gets 504 Gateway Timeout instead of waiting further. See the module docs for the cancellation caveat.
with_timeout_async
Wraps an AsyncAppWithState<S> handler so its future is dropped — genuinely cancelled at its next .await point — if it doesn’t resolve within duration. Backed by tokio::time::timeout; requires the http2 feature. No Clone bound on S: AsyncAppWithState already passes state as an owned Arc<S>.
with_timeout_state
Wraps an AppWithState<S> handler (which additionally receives &S) so it must complete within duration or the caller gets 504 Gateway Timeout instead of waiting further.