feat(http): respect Retry-After headers on HTTP 429 responses
Fixes: #6 Signed-off-by: Maximilian Marx <mmarx@wh2.tu-dresden.de>
This commit is contained in:
parent
4324ee17e8
commit
d553e81512
1 changed files with 24 additions and 3 deletions
|
@ -63,10 +63,31 @@ pub async fn nar_exists(client: Client, domain: &str, hash: &str, slide: u64) ->
|
||||||
match response {
|
match response {
|
||||||
Ok(response) if response.status().as_u16() == 200 => 1,
|
Ok(response) if response.status().as_u16() == 200 => 1,
|
||||||
Ok(response) if response.status().as_u16() == 404 => 0,
|
Ok(response) if response.status().as_u16() == 404 => 0,
|
||||||
_ => {
|
Ok(response) if response.status().as_u16() == 429 => {
|
||||||
// We're so fast now we get rate limited.
|
// We're so fast now we get rate limited.
|
||||||
//
|
|
||||||
// Writng an actual sliding window seems kinda hard,
|
let wait = if let Some(retry_after) = response.headers().get("Retry-After") {
|
||||||
|
if let Ok(seconds) = String::from_utf8_lossy(retry_after.as_bytes()).parse::<u64>() {
|
||||||
|
seconds * 1000
|
||||||
|
} else {
|
||||||
|
slide
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
slide
|
||||||
|
};
|
||||||
|
|
||||||
|
sleep(Duration::from_millis(wait)).await;
|
||||||
|
Box::pin(nar_exists(
|
||||||
|
client,
|
||||||
|
domain,
|
||||||
|
hash,
|
||||||
|
std::cmp::min(slide * 2, MAX_SLIDE),
|
||||||
|
))
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// We might also be out of sockets, so let's wait on that
|
||||||
|
// Writing an actual sliding window seems kinda hard,
|
||||||
// so we do this instead.
|
// so we do this instead.
|
||||||
log::trace!("rate limited! {slide}");
|
log::trace!("rate limited! {slide}");
|
||||||
sleep(Duration::from_millis(slide)).await;
|
sleep(Duration::from_millis(slide)).await;
|
||||||
|
|
Loading…
Reference in a new issue