Skip to content

Example in MethodRouter::layer documentation doesn't work #2582

@jorendorff

Description

@jorendorff

The docs for MethodRouter::layer contain this example:

use axum::{routing::get, Router};
use tower::limit::ConcurrencyLimitLayer;

async fn handler() {}

let app = Router::new().route(
    "/",
    // All requests to `GET /` will be sent through `ConcurrencyLimitLayer`
    get(handler).layer(ConcurrencyLimitLayer::new(64)),
);

This compiles, but no concurrency limit is enforced. This is because each request to GET / is sent through a different ConcurrencyLimit instance, each with its own semaphore.

Full runnable example (test with hey -n 50 http://localhost:3000/api/test):

use axum::{routing::get, Router};
use std::time::Duration;
use tower::limit::ConcurrencyLimitLayer;

async fn handler() {
    eprintln!("/api/test in");
    tokio::time::sleep(Duration::from_secs(1)).await;
    eprintln!("/api/test out");
}

#[tokio::main]
async fn main() {
    let app = Router::new().route(
        "/api/test",
        get(handler).layer(ConcurrencyLimitLayer::new(5)),
    );

    // run our app with hyper, listening globally on port 3000
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-axumC-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions