///|
/// GitHub's retry rule: a secondary rate limit is waited out and retried;
/// everything else follows `policy`.
pub(all) struct GitHubRetry {
policy : @runtime.RetryPolicy
}
///|
/// Exposes the retry decision as a method.
pub extend GitHubRetry with @runtime.RetryDecider::{next_delay_ms}
///|
/// Retries secondary limits regardless of request idempotency, within the
/// policy's retry count and server-delay cap.
pub impl @runtime.RetryDecider for GitHubRetry with fn next_delay_ms(
self,
error,
request,
attempt,
random,
) {
if !is_secondary_rate_limit(error) {
return self.policy.next_delay_ms(error, request, attempt, random)
}
if attempt >= self.policy.max_retries {
return None
}
let headers = match error {
@runtime.Status(headers~, ..) | @runtime.RateLimited(headers~, ..) =>
headers
_ => return None
}
let delay = match @http.retry_after_ms(headers) {
Some(ms) => ms
None => {
let mut ms = 60000
for _ in 0.. self.policy.max_retry_after_ms || ms > 1073741823 {
return None
}
ms *= 2
}
ms
}
}
if delay > self.policy.max_retry_after_ms {
None
} else {
Some(delay)
}
}