Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust GitHub rate limiting behavior. #1820

Merged
merged 2 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ pub fn to_human(d: DateTime<Utc>) -> String {
#[async_trait]
impl<'a> Action for Step<'a> {
async fn call(&self) -> anyhow::Result<String> {
let gh = GithubClient::new_from_env();
let mut gh = GithubClient::new_from_env();
gh.set_retry_rate_limit(true);

let mut context = Context::new();
let mut results = HashMap::new();
Expand Down
28 changes: 19 additions & 9 deletions src/github.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ impl GithubClient {
.with_context(|| format!("building reqwest {}", req_dbg))?;

let mut resp = self.client.execute(req.try_clone().unwrap()).await?;
if let Some(sleep) = Self::needs_retry(&resp).await {
resp = self.retry(req, sleep, MAX_ATTEMPTS).await?;
if self.retry_rate_limit {
if let Some(sleep) = Self::needs_retry(&resp).await {
resp = self.retry(req, sleep, MAX_ATTEMPTS).await?;
}
}
let maybe_err = resp.error_for_status_ref().err();
let body = resp
Expand All @@ -51,7 +53,10 @@ impl GithubClient {
const REMAINING: &str = "X-RateLimit-Remaining";
const RESET: &str = "X-RateLimit-Reset";

if resp.status().is_success() {
if !matches!(
resp.status(),
StatusCode::FORBIDDEN | StatusCode::TOO_MANY_REQUESTS
) {
return None;
}

Expand All @@ -60,12 +65,6 @@ impl GithubClient {
return None;
}

// Weird github api behavior. It asks us to retry but also has a remaining count above 1
// Try again immediately and hope for the best...
if headers[REMAINING] != "0" {
return Some(Duration::from_secs(0));
}

let reset_time = headers[RESET].to_str().unwrap().parse::<u64>().unwrap();
Some(Duration::from_secs(Self::calc_sleep(reset_time) + 10))
}
Expand Down Expand Up @@ -2149,6 +2148,8 @@ pub struct GithubClient {
api_url: String,
graphql_url: String,
raw_url: String,
/// If `true`, requests will sleep if it hits GitHub's rate limit.
retry_rate_limit: bool,
}

impl GithubClient {
Expand All @@ -2159,6 +2160,7 @@ impl GithubClient {
api_url,
graphql_url,
raw_url,
retry_rate_limit: false,
}
}

Expand All @@ -2174,6 +2176,14 @@ impl GithubClient {
)
}

/// Sets whether or not this client will retry when it hits GitHub's rate limit.
///
/// Just beware that the retry may take a long time (like 30 minutes,
/// depending on various factors).
pub fn set_retry_rate_limit(&mut self, retry: bool) {
self.retry_rate_limit = retry;
}

pub fn raw(&self) -> &Client {
&self.client
}
Expand Down
Loading