Add an admin endpoint to reset a key's limiter state
Nobody has started this yet — be first.
Business impact
"A customer got wrongly throttled" is a routine support request -- shared office IPs, a retry storm, a bug on the customer's side that looked like abuse from ours. Today the only remediation is "wait it out" or "restart the service" (which resets every customer's state, not just theirs). An operator-facing reset endpoint turns a multi-team escalation into a 30-second fix.
Problem
A Resetter interface (Reset(ctx, key) error) already exists as scaffolding in pkg/ratelimit/limiter.go, but nothing implements it yet, and there is no admin route to call it.
Current behavior
Once a key is rate-limited, there is no way to clear its state short of waiting out the window/refill, restarting the process (memory backend), or manually deleting the exact Redis key by hand (Redis backend).
Expected behavior
All six limiter types implement Resetter, restoring a key to a fresh/fully-available state. A new POST /api/v1/reset endpoint (body {"rule","key"}) looks up the rule like /api/v1/check does, type-asserts to Resetter, and returns 204 on success, 404 for an unknown rule, or 501 if the limiter doesn't support Resetter. After a successful reset, the key behaves exactly as if never used.
Steps to reproduce
- Exhaust a rule's limit for a key via repeated POST /api/v1/check calls until a 429 is returned.
- POST /api/v1/reset with the same rule/key.
- Observe: 404, because the route does not exist yet -- there is no way to clear the key's state.
Why this matters
Every production rate limiter needs an operator escape hatch. Without one, "a customer got wrongly throttled" turns into "wait or restart the service," neither of which is acceptable for anything but a toy.
Suggested approach
Memory implementations: state lives in a sync.Map keyed by the same string Allow/AllowN use -- Reset just deletes that entry so the next access recreates a fresh one via the existing LoadOrStore path. Redis implementations: Reset is a DEL on prefix+key, mirroring how the Lua scripts build their key -- check whether the redis.Scripter field type needs widening to expose Del without breaking existing constructors. Wire the route in router.go next to POST /api/v1/check, handler next to handleCheck.
Acceptance criteria
- All six limiter types implement ratelimit.Resetter
- POST /api/v1/reset with a valid rule/key returns 204 and the key's state is actually cleared (verified behaviorally, not just "no error")
- Unknown rule -> 404
- go test ./test/ -run TestTask05 -v passes
Verification
go test ./test/ -run TestTask05 -v
Hints (0/2)
Try it without hints first — the reading is the exercise.
Working on this ticket
Work on a branch named for the ticket — that's what you'll submit.
Branch off your fork
$git checkout -b feat/reset-endpointFix it and commit
Meet every acceptance criterion, and add a test that would have caught this.
Push the branch
$git push -u origin feat/reset-endpointSubmit it below
Paste your fork URL and the branch name, with a short write-up of the root cause.
Questions
Stuck on something?
Ask about anything unclear in the ticket — the maintainer and anyone who has solved it can answer. Please don't post full solutions.
Sign in to ask a question or reply.
Sign in