Repository navigation
Conversation
| // DecrementScript atomically decrements a rate limit counter, floored at 0. | ||
| // If the key does not exist there is nothing to refund, so it returns 0 without | ||
| // creating a phantom key. | ||
| const DecrementScript = ` |
There was a problem hiding this comment.
This is not really a common limiter part, moved it closer to Redis backend impl
There was a problem hiding this comment.
Reused driver.go as much as possible but this routine has quite independent connection cycle so decided not to bother too much
| if hitsAddends[i].IsNegative { | ||
| pipelineAppendDecrement(client, p, cacheKey.Key, hitsAddends[i].Value, &results[i], expirationSeconds) | ||
| // The subscriber listens only on the main Redis. | ||
| publishInvalidation := this.publishInvalidations && !onPerSecondRedis |
There was a problem hiding this comment.
dedicated per second redis assume high load and redis-backed refunds are barely effective here, not doing them (and the invalidator only listens main redis at the moment)
0602802 to
ef92df1
Compare
|
@collin-lee as a first-time contributor I do not have an opportunity to request for the review it looks like, so pinging you here :) |
rudrakhp
left a comment
There was a problem hiding this comment.
Thanks for the bug fix. Can we keep it focused on fixing the cache invalidation part though, any reason why we need the ENABLE_NEGATIVE_HITS flag?
|
@rudrakhp The reason is that the bug is still present - I did not support the same invalidation for the memcached backend case as I am not sure how to deliver it properly. So without ENABLE_NEGATIVE_HITS and with local overlimit cache enabled memcached-backed workload will silently keep working in a broken way |
|
@oclaw ok on second thought I think preventing RLS to come up with known unsupported combinations like Memcached + local cache + enable_negative_hits combination makes sense. SGTM. |
ef92df1 to
0de2a9c
Compare
| ) | ||
| if withLocalCache { | ||
| localCacheGuard = limiter.NewLocalCacheGuard(localCache) | ||
| publishInvalidations = s.EnableNegativeHits && localCacheGuard != nil |
There was a problem hiding this comment.
Shouldn't publishInvalidations be set without local cache as well? We seem to be setting it only if withLocalCache.
There was a problem hiding this comment.
Yeah, the condition need to be a bit different. Gated it on the fact if the negative hits are enabled at all, not on the local cache
| if ARGV[3] == '1' then | ||
| local limit = tonumber(ARGV[4]) | ||
| if old > limit and new_val <= limit then | ||
| redis.call('PUBLISH', ARGV[5], KEYS[1]) |
There was a problem hiding this comment.
Since we can override limits in requests, I think it is safer to refund regardless of old>limit?
| if ARGV[3] == '1' then | |
| local limit = tonumber(ARGV[4]) | |
| if old > limit and new_val <= limit then | |
| redis.call('PUBLISH', ARGV[5], KEYS[1]) | |
| if ARGV[3] == '1' and new_val < old then | |
| redis.call('PUBLISH', ARGV[5], KEYS[1]) |
There was a problem hiding this comment.
Makes sense. Switched to publish of every decrement, should be good
| // It owns one raw connection instead of reusing the driver's clients: radix | ||
| // pub/sub wraps a single Conn (pooled clients cannot subscribe), and losing | ||
| // it must never take the process down — the loop reconnects forever. |
There was a problem hiding this comment.
Can you explain a bit further? Don't think this warrants entire connection lifecycle management from scratch. I was expecting existing machinery to be good enough while we provide the invalidation logic only.
There was a problem hiding this comment.
It is still better to use an independent connection management here (this pipeline does not need a pool and is intended to operate on long-living connections), that's why I've implemented this machinery. But you're right that it is possible to reuse pretty much all of the dialing stuff from the driver, so baked it into the custom dialer function returned by the driver
2453e8c to
86ea20c
Compare
…cal cache on refunds Signed-off-by: Daniil Kogtev <oclaw@icloud.com>
- reuse dial from driver - simplify Lua script to publish on every decrement - publish always on negative hits enabled Signed-off-by: Daniil Kogtev <oclaw@icloud.com>
86ea20c to
07387a3
Compare
|
@rudrakhp any chance you can review it again? |
Problem
is_negative_hits (#1140) lets a descriptor decrement previously consumed quota, but refunds are invisible to the local over-limit cache: once a replica cached a key as over limit, a refund that freed quota in Redis kept being answered OVER_LIMIT from every replica's local cache until the window ended which degrades the feature on long windows
Suggested design
P.S. Agent also added some missing tests for touched components, look fine