Skip to content

Commit

Permalink
Merge pull request #1820 from ehuss/fix-retry
Browse files Browse the repository at this point in the history
Adjust GitHub rate limiting behavior.
  • Loading branch information
ehuss authored Jun 6, 2024
2 parents 54cd575 + e5e4c92 commit 4fe2183
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 10 deletions.
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

0 comments on commit 4fe2183

Please sign in to comment.