mirror of
https://github.com/ModernRelay/omnigraph.git
synced 2026-06-12 01:45:14 +02:00
server: emit Retry-After header on 429 / 503 responses
Closes the doc-vs-code gap at api.rs:343 and lib.rs:344-355: the documentation claims `Retry-After` is set on TooManyRequests / ServiceUnavailable responses, but `IntoResponse for ApiError` emitted only `(StatusCode, Json(ErrorOutput))` — no header. Wires a constant `RETRY_AFTER_SECONDS = "60"` for both 429 and 503 codes. Plumbing per-RejectReason durations through is a follow-up; the admission rejects we surface today recover bounded by request handler duration rather than calendar wait, so a constant suffices. Pinned by `ingest_per_actor_admission_cap_returns_429`. Test now fully green: 1+ of 8 concurrent /ingest under cap=1 receives 429 with Retry-After: 60. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
05a8bd5de1
commit
c745dd69ae
1 changed files with 19 additions and 0 deletions
|
|
@ -467,10 +467,29 @@ fn summarize_merge_conflicts(conflicts: &[api::MergeConflictOutput]) -> String {
|
||||||
format!("merge conflicts: {}{}", preview.join("; "), suffix)
|
format!("merge conflicts: {}{}", preview.join("; "), suffix)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Constant `Retry-After` value (seconds) emitted on 429 / 503 responses.
|
||||||
|
/// Matches the doc claim at `ApiError::too_many_requests` and
|
||||||
|
/// `ApiError::service_unavailable`. Plumbing per-RejectReason durations
|
||||||
|
/// through is a follow-up; the admission rejects we surface today are
|
||||||
|
/// uniformly bounded by the in-flight cap recovery time, which is
|
||||||
|
/// dominated by request handler duration rather than calendar wait.
|
||||||
|
const RETRY_AFTER_SECONDS: &str = "60";
|
||||||
|
|
||||||
impl IntoResponse for ApiError {
|
impl IntoResponse for ApiError {
|
||||||
fn into_response(self) -> Response {
|
fn into_response(self) -> Response {
|
||||||
|
let mut headers = axum::http::HeaderMap::new();
|
||||||
|
if matches!(
|
||||||
|
self.code,
|
||||||
|
ErrorCode::TooManyRequests | ErrorCode::ServiceUnavailable
|
||||||
|
) {
|
||||||
|
headers.insert(
|
||||||
|
axum::http::header::RETRY_AFTER,
|
||||||
|
axum::http::HeaderValue::from_static(RETRY_AFTER_SECONDS),
|
||||||
|
);
|
||||||
|
}
|
||||||
(
|
(
|
||||||
self.status,
|
self.status,
|
||||||
|
headers,
|
||||||
Json(ErrorOutput {
|
Json(ErrorOutput {
|
||||||
error: self.message,
|
error: self.message,
|
||||||
code: Some(self.code),
|
code: Some(self.code),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue