use std::sync::Arc;
use axum::{
body::Body,
extract::Request,
middleware::Next,
response::{IntoResponse, Response},
};
use tokio::sync::Semaphore;
use crate::rest::{
RestError,
middleware::{MiddlewareMetrics, record_resilience_event},
};
pub async fn concurrency_middleware(
semaphore: Arc<Semaphore>,
metrics: MiddlewareMetrics,
request: Request<Body>,
next: Next,
) -> Response {
let permit = match semaphore.try_acquire_owned() {
Ok(permit) => permit,
Err(_) => {
record_resilience_event(&metrics, "concurrency", "rejected");
return RestError::ConcurrencyLimit.into_response();
}
};
record_resilience_event(&metrics, "concurrency", "allowed");
let response = next.run(request).await;
drop(permit);
response
}