Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
📝 WalkthroughWalkthroughAdds batch rate-limiting support and integrates it into key validation. Introduces RatelimitMany API, refactors service internals (bucket identity, locking, window calculation), and updates validation to call batched checks. Adds tests verifying multi-limit behavior and non-leaky counters when one limit rejects a request. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Client
participant API as API VerifyKey Route
participant Keys as Keys Validation
participant RL as Ratelimit Service
Client->>API: VerifyKey request
API->>Keys: Validate(key)
Keys->>Keys: Collect rate limits to check
alt 0 limits
Keys-->>API: Valid (no ratelimits)
else 1 limit
Keys->>RL: Ratelimit(req)
RL->>RL: Evaluate bucket/window
RL-->>Keys: Response (allowed/exceeded, remaining)
else >1 limits
Keys->>RL: RatelimitMany(reqs[])
RL->>RL: Lock buckets, evaluate all
RL-->>Keys: Responses[]
end
Keys->>Keys: Map responses to per-limit results
Keys-->>API: Validation result (valid/ratelimited, per-limit states)
API-->>Client: HTTP response (status, headers)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Suggested labels
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (5)
🚧 Files skipped from review as they are similar to previous changes (1)
🧰 Additional context used🧬 Code graph analysis (3)go/internal/services/keys/validation.go (2)
go/apps/api/routes/v2_keys_verify_key/ratelimit_response_test.go (3)
go/internal/services/ratelimit/service.go (5)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
go/apps/api/routes/v2_keys_verify_key/multiple_ratelimits_overcommit_test.go(1 hunks)go/apps/api/routes/v2_ratelimit_limit/handler.go(1 hunks)go/internal/services/keys/validation.go(1 hunks)go/internal/services/ratelimit/interface.go(1 hunks)go/internal/services/ratelimit/service.go(5 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
go/apps/api/routes/v2_keys_verify_key/multiple_ratelimits_overcommit_test.go (5)
go/pkg/testutil/http.go (2)
NewHarness(55-189)CallRoute(271-305)go/apps/api/routes/v2_ratelimit_limit/handler.go (3)
Handler(36-45)Request(32-32)Response(33-33)go/pkg/testutil/seed/seed.go (1)
CreateRatelimitRequest(306-314)go/apps/api/openapi/gen.go (2)
VALID(43-43)RATELIMITED(41-41)go/pkg/ptr/deref.go (1)
SafeDeref(35-44)
go/apps/api/routes/v2_ratelimit_limit/handler.go (1)
go/internal/services/ratelimit/interface.go (1)
RatelimitRequest(62-103)
go/internal/services/ratelimit/service.go (5)
go/pkg/clock/interface.go (1)
Clock(12-24)go/pkg/counter/interface.go (1)
Counter(21-147)go/internal/services/ratelimit/interface.go (2)
RatelimitRequest(62-103)RatelimitResponse(110-146)go/pkg/buffer/buffer.go (1)
Buffer(14-23)go/pkg/prometheus/metrics/ratelimit.go (1)
RatelimitDecision(112-121)
go/internal/services/ratelimit/interface.go (1)
go/pkg/db/models_generated.go (1)
Ratelimit(736-747)
go/internal/services/keys/validation.go (2)
go/internal/services/ratelimit/interface.go (1)
RatelimitRequest(62-103)go/internal/services/keys/status.go (1)
StatusRateLimited(21-21)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Test Go API Local / Test
- GitHub Check: Test API / API Test Local
- GitHub Check: Build / Build
* refactor: deduplicate and make more maintaianable * test: correct remaining counts * fix: span attributes
fix: reject ratelimit changes
|
Thank you for following the naming conventions for pull request titles! 🙏 |
…fy_ratelimit_state

What does this PR do?
Fixes a critical bug where multiple rate limits cause incorrect counter decrements when one limit is triggered. When a key has multiple rate limits (e.g., 12/minute and 200/month), and the first limit gets checked and incremented, then the second limit is triggered, the first limit's counter remains incremented even though the request was rejected.
This PR implements an atomic batch processing approach for rate limits, ensuring that when any rate limit check fails, none of the counters are incremented. This prevents counter leaks and ensures users aren't rate limited too early.
Fixes #
Type of change
How should this be tested?
multiple_ratelimits_overcommit_test.gowhich verifies that monthly counters aren't decremented when minute limits are hitChecklist
Required
pnpm buildpnpm fmtconsole.logsgit pull origin main