429 status code for RateLimitLayer #1760
Answered
by
davidpdrsn
kimbauters
asked this question in
Q&A
-
I have a follow-up question from #987 . What is the best way to produce a 429 error when the rate limit is reached? A hack-y approach is to abuse the
But this doesn't feel quite right. Is there a better way to do this? |
Beta Was this translation helpful? Give feedback.
Answered by
davidpdrsn
Feb 16, 2023
Replies: 1 comment 1 reply
-
Here is an example: use std::time::Duration;
use axum::{
error_handling::HandleErrorLayer,
http::StatusCode,
response::{IntoResponse, Response},
routing::get,
BoxError, Router,
};
use tower::{
buffer::BufferLayer,
limit::RateLimitLayer,
load_shed::{error::Overloaded, LoadShedLayer},
ServiceBuilder,
};
#[tokio::main]
async fn main() {
let app = Router::new().route("/", get(|| async {})).layer(
ServiceBuilder::new()
.layer(HandleErrorLayer::new(handle_error))
.layer(BufferLayer::new(1024))
.layer(LoadShedLayer::new()) // <- this
.layer(RateLimitLayer::new(1, Duration::from_secs(5))),
);
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
}
async fn handle_error(error: BoxError) -> Response {
if error.is::<Overloaded>() {
(StatusCode::TOO_MANY_REQUESTS, "calm down plzz").into_response()
} else {
(StatusCode::INTERNAL_SERVER_ERROR, "Something went wrong").into_response()
}
} |
Beta Was this translation helpful? Give feedback.
1 reply
Answer selected by
kimbauters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
RateLimit
will send backpressure up the stack making things wait. To convert that "not ready" state into an error you needLoadShed
.Here is an example: