Add 429 retry/backoff to Grain API client - #7
Draft
dplakon wants to merge 1 commit into
Draft
Conversation
Grain throttles bursts of requests during rapid pagination, causing the daily meeting fetch to fail with HTTP 429 on the second page. Wrap all Grain HTTP calls in a shared _request helper that retries 429 responses with exponential backoff, honoring the Retry-After header when present. Retry count and base backoff are configurable via env vars. Co-Authored-By: Oz <oz-agent@warp.dev>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
While running the daily Grainiac orchestrator to process today's meetings,
scripts/fetch_daily_meetings.pyconsistently failed withHTTP Error 429: Too Many Requests. The first page of/recordingssucceeded, but the immediately-following cursor request was rate-limited — Grain throttles bursts of requests during rapid pagination. The client had no retry/backoff, so the whole fetch aborted.Change
_requesthelper inscripts/grain_client.pythat retries429responses with exponential backoff, honoring theRetry-Afterheader when the server provides one._get(list/detail) andget_transcript_textthrough the helper so pagination and transcript fetches are both resilient.GRAINIAC_GRAIN_MAX_RETRIES(default 5) andGRAINIAC_GRAIN_BACKOFF_SECONDS(default 2).Verification
After the change, the fetch completed successfully: pagination retried each transient 429 once and scanned all 2000 recent recordings. For
2026-07-26there were 0 external customer meetings, so no child agents were spawned (per the orchestrator skill).Conversation: https://app.warp.dev/conversation/fd71ff24-6c87-4f71-9517-92864b8876f1
Run: https://oz.warp.dev/runs/019fa1f1-bf28-7cea-a5e4-d2f9c50f36c9
This PR was generated with Oz.