MCPcopy Create free account
hub / github.com/github/gh-aw / waitForOrgRateLimit

Function waitForOrgRateLimit

pkg/cli/update_org.go:258–319  ·  view source on GitHub ↗
(ctx context.Context, resource string, verbose bool)

Source from the content-addressed store, hash-verified

256}
257
258func waitForOrgRateLimit(ctx context.Context, resource string, verbose bool) error {
259 output, err := workflow.RunGHContext(ctx, "Checking rate limit...", "api", "rate_limit")
260 if err != nil {
261 return err
262 }
263
264 var response orgRateLimitResponse
265 if err := json.Unmarshal(output, &response); err != nil {
266 return err
267 }
268
269 limit := response.Resources.Core
270 buffer := orgUpdateCoreBuffer
271 if resource == "search" {
272 limit = response.Resources.Search
273 buffer = orgUpdateSearchBuffer
274 }
275 if limit.Limit == 0 {
276 return nil
277 }
278
279 orgUpdateLog.Printf("GitHub %s rate limit: %d/%d remaining (reset at %s)", resource, limit.Remaining, limit.Limit, time.Unix(limit.Reset, 0).Format(time.RFC3339))
280
281 // Critical level: once consumption reaches limit-1000 API units, stop processing
282 // additional work rather than risking quota exhaustion or a long reset wait. The
283 // search resource has a tiny quota, so the critical threshold only applies to core.
284 if resource != "search" {
285 criticalRemaining := limit.Limit - orgUpdateCriticalConsumed
286 if criticalRemaining > buffer && limit.Remaining <= criticalRemaining {
287 orgUpdateLog.Printf("GitHub %s rate limit critical: %d/%d remaining (<= %d)", resource, limit.Remaining, limit.Limit, criticalRemaining)
288 fmt.Fprintln(os.Stderr, console.FormatWarningMessage(
289 fmt.Sprintf("GitHub %s API budget critical: %d/%d remaining (consumed %d API units)", resource, limit.Remaining, limit.Limit, limit.Limit-limit.Remaining),
290 ))
291 return errOrgRateLimitCritical
292 }
293 }
294
295 if limit.Remaining <= buffer {
296 resetAt := time.Unix(limit.Reset, 0)
297 waitFor := time.Until(resetAt) + rateLimitResetBuffer
298 if waitFor > 0 {
299 fmt.Fprintln(os.Stderr, console.FormatWarningMessage(
300 fmt.Sprintf("Applying a %s delay to avoid reaching the GitHub %s rate limit (%d/%d remaining)", waitFor.Round(time.Second), resource, limit.Remaining, limit.Limit),
301 ))
302 timer := time.NewTimer(waitFor)
303 defer timer.Stop()
304 select {
305 case <-ctx.Done():
306 return ctx.Err()
307 case <-timer.C:
308 }
309 return nil
310 }
311 }
312
313 if verbose {
314 fmt.Fprintln(os.Stderr, console.FormatVerboseMessage(
315 fmt.Sprintf("GitHub %s rate limit OK: %d/%d remaining", resource, limit.Remaining, limit.Limit),

Callers

nothing calls this directly

Calls 6

RunGHContextFunction · 0.92
FormatWarningMessageFunction · 0.92
FormatVerboseMessageFunction · 0.92
DoneMethod · 0.80
PrintfMethod · 0.45
StopMethod · 0.45

Tested by

no test coverage detected