Skip to content

Commit 0c56d1b

Browse files
authored
Refactor retry-after logic (#2210)
2 parents 70d82e9 + d2e801e commit 0c56d1b

File tree

2 files changed

+26
-13
lines changed

2 files changed

+26
-13
lines changed

ChangeLog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## Unreleased
4+
* Server: Respect `retry-after` header on error responses (within limits) (thanks [@vinay0826])
5+
6+
[@vinay0826]: https://github.com/vinay0826
7+
38
## Version 1.86.0
49
* Server: Fix non-determinism with regards to overrides of specific header names
510
* Server: Bump MSRV to 1.88.0

server/svix-server/src/worker.rs

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,11 @@ struct WorkerContext<'a> {
256256
webhook_client: &'a WebhookClient,
257257
}
258258

259-
struct FailedDispatch(messageattempt::ActiveModel, Error, Option<DateTime<Utc>>);
259+
struct FailedDispatch {
260+
attempt: messageattempt::ActiveModel,
261+
err: Error,
262+
retry_after: Option<DateTime<Utc>>,
263+
}
260264

261265
struct SuccessfulDispatch(messageattempt::ActiveModel);
262266

@@ -388,9 +392,9 @@ async fn make_http_call(
388392
} else {
389393
None
390394
};
391-
let response_headers = res.headers().clone();
392395

393-
let body = match res.into_body().collect().await {
396+
let (res_parts, body) = res.into_parts();
397+
let body = match body.collect().await {
394398
Ok(collected) => {
395399
let bytes = collected.to_bytes();
396400
if bytes.len() > RESPONSE_MAX_SIZE {
@@ -412,12 +416,12 @@ async fn make_http_call(
412416

413417
match http_error {
414418
Some(err) => {
415-
let retry_after = retry_after(&response_headers);
416-
Ok(CompletedDispatch::Failed(FailedDispatch(
419+
let retry_after = retry_after(&res_parts.headers);
420+
Ok(CompletedDispatch::Failed(FailedDispatch {
417421
attempt,
418-
Error::generic(err),
422+
err: Error::generic(err),
419423
retry_after,
420-
)))
424+
}))
421425
}
422426
None => Ok(CompletedDispatch::Successful(SuccessfulDispatch(attempt))),
423427
}
@@ -426,17 +430,17 @@ async fn make_http_call(
426430
// For errors, we still calculate the duration
427431
let duration_ms = (Utc::now() - created_at).num_milliseconds();
428432

429-
Ok(CompletedDispatch::Failed(FailedDispatch(
430-
messageattempt::ActiveModel {
433+
Ok(CompletedDispatch::Failed(FailedDispatch {
434+
attempt: messageattempt::ActiveModel {
431435
response_status_code: Set(0),
432436
response: Set(err.to_string()),
433437
status: Set(MessageStatus::Fail),
434438
response_duration_ms: Set(duration_ms),
435439
..attempt
436440
},
437-
err.into(),
438-
None,
439-
)))
441+
err: err.into(),
442+
retry_after: None,
443+
}))
440444
}
441445
}
442446
}
@@ -561,7 +565,11 @@ async fn handle_failed_dispatch(
561565
msg_task,
562566
..
563567
}: DispatchContext<'_>,
564-
FailedDispatch(mut attempt, err, retry_after): FailedDispatch,
568+
FailedDispatch {
569+
mut attempt,
570+
err,
571+
retry_after,
572+
}: FailedDispatch,
565573
) -> Result<()> {
566574
attempt.ended_at = Set(Some(Utc::now().into()));
567575

0 commit comments

Comments
 (0)