From 7d1637d89ad8be912a1579f3004a6e003e74cfb6 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Wed, 5 May 2021 15:27:44 -0700 Subject: [PATCH] RpcClient now respects the retry-after server response header when getting rate limited --- client/src/http_sender.rs | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/client/src/http_sender.rs b/client/src/http_sender.rs index e80adea68..9c3f98a9b 100644 --- a/client/src/http_sender.rs +++ b/client/src/http_sender.rs @@ -7,7 +7,11 @@ use { rpc_sender::RpcSender, }, log::*, - reqwest::{self, header::CONTENT_TYPE, StatusCode}, + reqwest::{ + self, + header::{CONTENT_TYPE, RETRY_AFTER}, + StatusCode, + }, std::{ sync::{ atomic::{AtomicU64, Ordering}, @@ -83,14 +87,24 @@ impl RpcSender for HttpSender { if response.status() == StatusCode::TOO_MANY_REQUESTS && too_many_requests_retries > 0 { + let mut duration = Duration::from_millis(500); + if let Some(retry_after) = response.headers().get(RETRY_AFTER) { + if let Ok(retry_after) = retry_after.to_str() { + if let Ok(retry_after) = retry_after.parse::() { + if retry_after < 120 { + duration = Duration::from_secs(retry_after); + } + } + } + } + too_many_requests_retries -= 1; debug!( - "Server responded with {:?}, {} retries left", - response, too_many_requests_retries + "Too many requests: server responded with {:?}, {} retries left, pausing for {:?}", + response, too_many_requests_retries, duration ); - // Sleep for 500ms to give the server a break - sleep(Duration::from_millis(500)); + sleep(duration); continue; } return Err(response.error_for_status().unwrap_err().into());