feat(api): add rate limiter#2157
Conversation
| } | ||
| cleanupFns = append(cleanupFns, func(_ context.Context) error { | ||
| return redisClient.Close() | ||
| }) |
There was a problem hiding this comment.
Redis client closed concurrently with dependent cache cleanup
Low Severity
Moving Redis client creation out of APIStore and adding its Close as a separate entry in cleanupFns introduces a race condition during shutdown. All cleanup functions run in parallel goroutines, so redisClient.Close() can complete while apiStore.Close() is still executing Redis-dependent operations like snapshotCache.Close(), templateCache.Close(), and templateBuildsCache.Close(). Previously, the Redis client was closed at the end of apiStore.Close(), ensuring sequential ordering. Now these run concurrently, causing spurious errors during shutdown.
Additional Locations (2)
|
|
||
| logger.L().Warn(ctx, "rate limit exceeded", | ||
| logger.WithTeamID(teamID), | ||
| zap.Int("retry_after_s", retryAfterSecs), |
There was a problem hiding this comment.
lets add also the rate limit fields, ideally set them on the logger early and reuse the instance
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
* feat(api): add rate limiter for some endpoints * chore: make tidy * Update packages/api/internal/middleware/ratelimit/ratelimit.go * Apply suggestion from @jakubno * chore: generalize the rate limiter * fix: close redis and feature flags client correctly * fix: test * fix: lint * chore: pr comments * fix: test


Note
Medium Risk
Adds a Redis-backed rate limiting middleware into the API request path, which can return new
429/500responses when enabled and depends on Redis availability and correct LaunchDarkly flag configuration.Overview
This PR introduces a per-team, Redis-backed rate limiter for API requests (using
go-redis/redis_rate) and wires it into the Gin server behind a new LaunchDarkly kill-switch flag, with optional per-route rate/burst overrides driven by a JSON flag; it also refactors startup soRedisand the feature-flag client are initialized inmainand injected intoAPIStore/server construction, and adds unit/integration tests covering fail-open/closed behavior, headers, burst/refill, and concurrency.Written by Cursor Bugbot for commit 0fcd39c. This will update automatically on new commits. Configure here.