fix: actions rate limit#164
Conversation
…s workflow - Add version check after OCR installation to verify successful setup - Implement exponential backoff retry logic for GitHub API rate limits - Add delays between individual comment posts to avoid secondary rate limits - GitHub enforces ~80 content-generating requests per minute; spacing calls helps stay under that threshold with 2-second base delay and up to 3 retries
- Add `|| true` to ocr version check for error isolation - Narrow rate limit detection to 429 and 403 with rate-limit message matching, avoiding retries on permission/auth failures - Extract hardcoded delay constants into env-configurable variables (OCR_RETRY_BASE_DELAY, OCR_MAX_RETRIES, OCR_SUCCESS_DELAY, OCR_FAILURE_DELAY) with sensible defaults - Document optional environment variables in workflow header
- Add `ocr version || true` after install for diagnostic logging - Add `api_request_with_retry` function with exponential backoff for 429 and 403 (rate-limit message matching) errors - Respect GitLab `Retry-After` header when present - Extract delay constants into CI/CD-configurable variables (OCR_RETRY_BASE_DELAY, OCR_MAX_RETRIES, OCR_SUCCESS_DELAY, OCR_FAILURE_DELAY) with defaults - Add pacing delays between successful/failed discussion posts - Document optional CI/CD variables in pipeline header comments
| } else { | ||
| failedCount++; | ||
| failedComments.push({ comment, error: innerE.message }); | ||
| console.log(`Failed to post comment for ${reviewComment.path}: ${innerE.message}`); | ||
| // Still delay after a non-rate-limit failure to pace subsequent requests | ||
| await sleep(FAILURE_DELAY); | ||
| } |
There was a problem hiding this comment.
Bug: When rate-limit retries are exhausted (i.e., isRateLimit === true but attempt === MAX_RETRIES), execution falls into this else branch, which only applies FAILURE_DELAY (default 1000ms). After repeatedly hitting rate limits, a 1-second pause before the next comment's API call is likely insufficient and may perpetuate rate-limit failures.
Additionally, the comment "Still delay after a non-rate-limit failure" is misleading because this branch also handles exhausted rate-limit retries.
Consider distinguishing between the two failure cases: apply a longer delay (e.g., the last computed backoff delay or SUCCESS_DELAY) when rate-limit retries are exhausted, and keep the shorter FAILURE_DELAY only for genuine non-rate-limit errors.
Suggestion:
| } else { | |
| failedCount++; | |
| failedComments.push({ comment, error: innerE.message }); | |
| console.log(`Failed to post comment for ${reviewComment.path}: ${innerE.message}`); | |
| // Still delay after a non-rate-limit failure to pace subsequent requests | |
| await sleep(FAILURE_DELAY); | |
| } | |
| } else { | |
| failedCount++; | |
| failedComments.push({ comment, error: innerE.message }); | |
| console.log(`Failed to post comment for ${reviewComment.path}: ${innerE.message}`); | |
| // After exhausting rate-limit retries, use a longer delay; for other errors, use a shorter pace delay | |
| const postFailDelay = isRateLimit ? RETRY_BASE_DELAY * Math.pow(2, MAX_RETRIES) : FAILURE_DELAY; | |
| await sleep(postFailDelay); | |
| } |
- GitHub Actions: distinguish exhausted rate-limit retries from other errors, apply SUCCESS_DELAY (2s) instead of FAILURE_DELAY (1s) when retries exhausted - GitLab CI: return structured result from api_request_with_retry to differentiate failure types, apply context-aware delays based on rate-limit exhaustion status - Both: prevent perpetuating rate-limit failures by using longer delays after retry exhaustion
|
Will perform some further tests before it can be merged. |
|
Thanks for issuing this, hit the same issue today. |
Derive wait durations from response headers (retry-after, x-ratelimit-reset) instead of fixed exponential backoff, add proactive throttle when remaining quota is low, honor batch-level rate limits before per-comment retry, and add support for transient 5xx/408 errors.
…elay, and proactive throttling - Add ±25% jitter on retry delays to avoid thundering herd problems - Add OCR_MAX_RETRY_DELAY (default 60s) to cap per-retry wait time - Add OCR_RATE_LIMIT_THRESHOLD (default 10) for proactive throttling based on GitLab RateLimit-Remaining response header - Parse Retry-After header properly (handle non-numeric values) - Apply retry logic to all API requests (notes, versions, discussions) - Parse and log RateLimit-Remaining/Limit headers for observability - Double pacing delay when remaining quota drops below threshold - Update README with new configuration variables and behavior docs
…ing variables - GitHub Actions README: fix OCR_RETRY_BASE_DELAY default from 2000 to 60000 (matching script code and header comments) - GitHub Actions README: add missing OCR_RETRY_MAX_DELAY, OCR_LOW_REMAINING_THRESHOLD, OCR_LOW_REMAINING_SPACING variables - GitHub Actions README: add GitHub Rate Limits doc reference link - GitHub Actions yml header: add OCR_LLM_USE_ANTHROPIC and llm.extra_body notes - GitLab CI yml header: add llm.extra_body note - GitLab CI README: add GitLab Rate Limits doc reference link
- GitHub Actions: extract inline header closure into a reusable getHeader helper; use it in both computeRetryDelayMs and logRateLimitQuota for consistent case-insensitive header access. - GitHub Actions: use a 2s transientBase for 5xx/408 exponential backoff instead of the 60s rate-limit base, since server hiccups are typically short-lived and the longer base stalled CI jobs unnecessarily. - GitLab CI: add a _get_header helper and route all header access (Retry-After, RateLimit-*) through it, matching the GitHub Actions approach. - GitLab CI: add transient retry logic for 5xx/408 errors with a 2s base delay, so server errors no longer fail immediately.
Description
Add rate-limit handling and version verification to both the GitHub Actions and GitLab CI example workflows. When posting many review comments via API, the original scripts could hit platform rate limits (GitHub's secondary rate limit of ~80 content-creating requests/min, and GitLab's general rate limit on self-hosted instances), causing comment posting failures with no recovery mechanism.
This PR introduces exponential backoff with retry logic, configurable delay constants, and a post-install version check for better observability.
Type of Change
How Has This Been Tested?
make testpasses locallyChecklist
go fmt,go vet)Related Issues
#158