fix: exhaust MovingWindowCallRatePolicy bucket when API reports 0 available calls - #1154
Open
devin-ai-integration[bot] wants to merge 1 commit into
Open
devin-ai-integration[bot] wants to merge 1 commit into
devin-ai-integration[bot] wants to merge 1 commit into
Conversation
…ilable calls Co-Authored-By: bot_apk <apk@cognition.ai>
Contributor
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
👋 Greetings, Airbyte Team Member!Here are some helpful tips and reminders for your convenience. 💡 Show Tips and TricksTesting This CDK VersionYou can test this version of the CDK using the following: # Run the CLI from this branch:
uvx 'git+https://github.com/airbytehq/airbyte-python-cdk.git@devin/1789428944-fix-moving-window-update#egg=airbyte-python-cdk[dev]' --help
# Update a connector to use the CDK from this branch ref:
cd airbyte-integrations/connectors/source-example
poe use-cdk-branch devin/1789428944-fix-moving-window-updatePR Slash CommandsAirbyte Maintainers can execute the following slash commands on your PR:
|
Airbyte Support Bot (airbyte-support-bot)
requested a lite review from Copilot
September 14, 2026 23:40
Copilot started reviewing on behalf of
Airbyte Support Bot (airbyte-support-bot)
September 14, 2026 23:40
View session
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
No unresolved review issues remain.
Pull request overview
Fixes moving-window rate-limit synchronization when an API reports zero available calls.
Changes:
- Exhausts the bucket across configured rate windows.
- Logs failed bucket synchronization.
- Adds regression coverage for exhaustion and edge cases.
File summaries
| File | Description |
|---|---|
unit_tests/sources/streams/test_call_rate.py |
Adds coverage for zero-call updates and edge cases. |
airbyte_cdk/sources/streams/call_rate.py |
Implements capacity calculation and bucket exhaustion. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Patrick Nilan (pnilan)
marked this pull request as ready for review
September 14, 2026 23:44
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.
Overview
👉 TL;DR: When an API tells the connector it has no calls left, the moving-window rate limiter was only recording a single extra call instead of marking the whole window as used, so connectors kept sending requests and hit HTTP 429s.
Specifically,
MovingWindowCallRatePolicy.update(available_calls=0, call_reset_ts=None)now fills theInMemoryBucketup to the strictest configuredRatevia a new_get_available_calls(now)helper.Resolves https://github.com/airbytehq/airbyte-internal-issues/issues/17242:
Changes
update()previously computeditems_to_add = self._bucket.count() < rates[0].limit(abool) and passed it asRateItem.weight;InMemoryBucket.put()doesitems.extend(weight * [item]), soTrueadded exactly one entry. It now computes an integer weight:put(), so the put fills the tightest window exactly (no-op when already full) and is accepted for multi-rate buckets.bucket.count()was also wrong because it includes entries outside the shortest window (leak()only drops entries older than the longest window).boolreturn ofbucket.put()is now checked; a warning is logged if the sync fails.available_calls > 0or whencall_reset_tsis provided.Review Spotlight
Reviewers with limited time, please review first:
call_rate.py#L485-L511: the new weight computationTest plan
freezegun-based tests inTestMovingWindowCallRatePolicy: 3-of-10 acquired thenupdate(0, None)blocks the next call and unblocks after the window expires; already-full bucket is a no-op; expired-but-not-leaked entries with two rates; three-rate bucket; positiveavailable_calls/ providedcall_reset_tsremain no-ops.test_update_available_calls_zero_exhausts_bucketfails onmain(assert 4 == 10) and passes with the fix.poetry run pytest unit_tests/sources/streams/test_call_rate.py -q(43 passed),poetry run ruff check .,poetry run ruff format .,poetry run mypy --config-file mypy.ini airbyte_cdk/sources/streams/call_rate.pyall pass.Requested via the
/ai-fixworkflow on the linked issue.Link to Devin session: https://app.devin.ai/sessions/7f1fa151fe884f51a6fdadf484f8048f
Open in Devin Desktop: https://app.devin.ai/desktop/session/7f1fa151fe884f51a6fdadf484f8048f?variant=devin