Sleep for ratelimit depletion also.
This commit is contained in:
parent
1811b60b06
commit
211d8681b2
@ -9,6 +9,8 @@ pub struct GithubEndpointWatcher {
|
|||||||
http_client: reqwest::Client,
|
http_client: reqwest::Client,
|
||||||
etag: Option<HeaderValue>,
|
etag: Option<HeaderValue>,
|
||||||
next_poll_allowed: u64,
|
next_poll_allowed: u64,
|
||||||
|
ratelimit_remaining: Option<u64>,
|
||||||
|
ratelimit_reset: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GithubEndpointWatcher {
|
impl GithubEndpointWatcher {
|
||||||
@ -25,6 +27,8 @@ impl GithubEndpointWatcher {
|
|||||||
http_client,
|
http_client,
|
||||||
etag: None,
|
etag: None,
|
||||||
next_poll_allowed: 0,
|
next_poll_allowed: 0,
|
||||||
|
ratelimit_remaining: None,
|
||||||
|
ratelimit_reset: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,29 +43,27 @@ impl GithubEndpointWatcher {
|
|||||||
request = request.header(reqwest::header::ETAG, etag);
|
request = request.header(reqwest::header::ETAG, etag);
|
||||||
}
|
}
|
||||||
self.sleep_until_next_poll().await?;
|
self.sleep_until_next_poll().await?;
|
||||||
|
self.sleep_until_ratelimit().await?;
|
||||||
let request_started_at = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
|
let request_started_at = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
|
||||||
println!("Hitting url {}", self.url);
|
println!("Hitting url {}", self.url);
|
||||||
let response = request.send().await?;
|
let response = request.send().await?;
|
||||||
|
|
||||||
let headers = response.headers();
|
let headers = response.headers();
|
||||||
let etag = headers.get(reqwest::header::ETAG).map(|x| x.to_owned());
|
let etag = headers.get(reqwest::header::ETAG).map(|x| x.to_owned());
|
||||||
let poll_interval = headers.get("x-poll-interval").map(|x| x.to_owned());
|
let poll_interval = number_header(headers.get("x-poll-interval"))?;
|
||||||
// let ratelimit_limit = headers.get("x-ratelimit-limit").map(|x| x.to_owned());
|
// let ratelimit_limit = headers.get("x-ratelimit-limit").map(|x| x.to_owned());
|
||||||
// let ratelimit_remaining = headers.get("x-ratelimit-remaining").map(|x| x.to_owned());
|
self.ratelimit_remaining = number_header(headers.get("x-ratelimit-remaining"))?;
|
||||||
// let ratelimit_reset = headers.get("x-ratelimit-reset").map(|x| x.to_owned());
|
self.ratelimit_reset = number_header(headers.get("x-ratelimit-reset"))?;
|
||||||
// let ratelimit_used = headers.get("x-ratelimit-used").map(|x| x.to_owned());
|
// let ratelimit_used = headers.get("x-ratelimit-used").map(|x| x.to_owned());
|
||||||
// let ratelimit_resource = headers.get("x-ratelimit-resource").map(|x| x.to_owned());
|
// let ratelimit_resource = headers.get("x-ratelimit-resource").map(|x| x.to_owned());
|
||||||
|
|
||||||
let body = response.json::<serde_json::Value>().await?;
|
let body = response.json::<serde_json::Value>().await?;
|
||||||
println!("{}", serde_json::to_string(&body)?);
|
println!("{}", serde_json::to_string(&body)?);
|
||||||
self.etag = etag;
|
self.etag = etag;
|
||||||
let poll_interval_parsed: u64 = match poll_interval {
|
let poll_interval_parsed: u64 = poll_interval.unwrap_or_else(|| {
|
||||||
Some(header) => header.to_str()?.parse()?,
|
|
||||||
None => {
|
|
||||||
println!("No poll interval returned, defaulting to 5 minute polling.");
|
println!("No poll interval returned, defaulting to 5 minute polling.");
|
||||||
300
|
300
|
||||||
}
|
});
|
||||||
};
|
|
||||||
self.next_poll_allowed = request_started_at + poll_interval_parsed;
|
self.next_poll_allowed = request_started_at + poll_interval_parsed;
|
||||||
Ok(body)
|
Ok(body)
|
||||||
}
|
}
|
||||||
@ -76,4 +78,35 @@ impl GithubEndpointWatcher {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn sleep_until_ratelimit(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
match self.ratelimit_remaining {
|
||||||
|
Some(remaining) if remaining <= 0 => {}
|
||||||
|
_ => {
|
||||||
|
// If the number of remaining requests is either
|
||||||
|
// unknown (None) or greater than 0, we do not need to
|
||||||
|
// sleep.
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let reset = self
|
||||||
|
.ratelimit_reset
|
||||||
|
.expect("The above match statement proves this is a Some()");
|
||||||
|
loop {
|
||||||
|
let now = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
|
||||||
|
if now >= reset {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sleep(Duration::from_secs(reset - now)).await;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn number_header(header: Option<&HeaderValue>) -> Result<Option<u64>, Box<dyn std::error::Error>> {
|
||||||
|
Ok(header
|
||||||
|
.map(|hdr| hdr.to_str())
|
||||||
|
.transpose()?
|
||||||
|
.map(|hdr| hdr.parse())
|
||||||
|
.transpose()?)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user