Fix threshold behavior to allow N requests instead of N-1 #46
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
This pull request fixes the core rate limiting bug where
threshold: Nwas incorrectly blocking requests on the Nth attempt instead of allowing N requests before blocking the (N+1)th request. This change aligns the actual implementation behavior with the original README documentation and user expectations (check this PR for more context).Background / Problem
The current implementation has a logical flaw in the rate limiting logic that contradicts the intuitive expectations. Here's what was happening:
Current (Buggy) Behavior
threshold: 1, the very first request gets blockedthreshold: 5, only 4 requests are allowed before the 5th is blockedthreshold: 15, only 14 requests are allowed before the 15th is blockedExpected Behavior
Users naturally expect
threshold: Nto mean "allow N requests per interval."Root Cause Analysis
The bug is in
/lib/graph_attack/rate_limit.rbin thecalls_exceeded_on_query?method:The problem: increment first, check second. This means:
Solution
Fixed the order of operations to check first, increment second:
Now the logic works correctly:
Testing
Added Explicit Test Cases for the Bug Fix
Documentation Updates
Updated
/README.mdto be crystal clear about the behavior:Before:
After: