The sustained gate stored one entry for every attempt, denied ones too, and summed all entries on each request. A flood grew memory with rate times interval and made each request slower. Both gates now keep only the newest limit plus one attempt times. A Lean proof shows this decides the same as the full count. One check dropped from 29,502 ns and 11 allocations to 43 ns and none. The go-ratecounter dependency is gone.
With an empty prefix, Clear deleted every key in the Redis database, including keys of other applications. Cache keys now start with gmp: by default. Existing cache entries become unreachable after the upgrade and expire by TTL.
The upgrade request passed the ban and rate-limit checks on its own headers. The backend then acted as the identity in the connection_init payload. A banned user could connect without credentials and send their token in the payload. The proxy now runs the same checks on the payload identity.
A retention of zero or less moved the delete cutoff to now or later. The cleaner then deleted all event history. The cleaner now refuses to start and returns an error.
The startup probe slept a full backoff step even when the deadline was closer. A 31 second timeout ended after about 41 seconds. The probe now sleeps no longer than the time left.
The count-based eviction removed a tenth of the cap. For a cap under ten, that was zero entries, so the cache grew without limit. The cache now evicts at least one entry when it is full.
The sustained gate compared requests per second with Req, which is a count per Interval. An interval of one minute with req 10 allowed 600 requests. The gate now compares the count in the interval with Req. One-second intervals behave as before. A burst at or above req has no effect, because the sustained gate always binds first.
Waiters read the primary response buffer while fasthttp could reuse it for another request. A waiter could then send the wrong body. The primary now gives waiters their own copy.
The sampler read the counter and then reset it in two steps. Requests recorded between the steps were lost. The sampler now swaps the counter to zero in one atomic step.
The refill loop dropped the fractional part of each tick. At 15 tokens per second and 100 ms ticks, it added 10 tokens per second instead of 15. The clock now advances only by the time the added tokens pay for.
CountQueries and CountQueriesWithPattern ran KEYS. With an empty
prefix, KEYS * builds a reply of every key on the server. The stats
endpoint calls it on each request. On a shared Dragonfly with about
1M keys, this raised memory on the server.
Count with a cursor SCAN instead. The count does not hold the key
list in memory. A test checks that no KEYS command is sent.
Version 0.1.12 had a data race between addValue and cleanUpOldValues. The
race detector in CI reported it in the burst test. Version 0.1.13 copies
the pooled values and the race is gone.
The v2 module path is github.com/sony/gobreaker/v2 and the breaker is
generic. The code instantiates it with any, which matches the v1
Execute signature.
miniredis 2.39 ignores the SCAN COUNT hint and returns every key in one
batch. The test now paginates SCAN in its own hook, so it no longer
depends on miniredis batching.