HY-love-sleep opened a new pull request, #7166:
URL: https://github.com/apache/shenyu/pull/7166
### Motivation
Fixes #6649. `recordTokensUsage` re-issued the expiration after every
increment:
```java
reactiveRedisTemplate.opsForValue()
.increment(cacheKey, tokens)
.flatMap(currentValue -> reactiveRedisTemplate.expire(cacheKey,
Duration.ofSeconds(windowSeconds)))
.subscribe();
```
so as long as requests kept arriving within `windowSeconds` the counter
never expired and the budget of the
window was never reset: "N tokens per window" behaved as a monotonic
lifetime cap, and sustained traffic
stayed throttled until a quiet period.
### What changed
The counter now gets its window when the key is created, and the expiration
is never re-issued:
```java
final ReactiveValueOperations valueOperations =
reactiveRedisTemplate.opsForValue();
valueOperations.setIfAbsent(cacheKey, 0L, Duration.ofSeconds(windowSeconds))
.then(valueOperations.increment(cacheKey, tokens))
.subscribe();
```
`SET NX` with a TTL creates the counter and its window in the same atomic
command, and `INCR` adds the usage
of the current request. A key that already exists keeps the window it was
created with, so the counter expires
on schedule and the first request of the next window starts from zero again.
I used `SET NX` + `INCR` rather than `INCR` + `EXPIRE NX` (the other option
suggested in the issue) because the
TTL is then attached by the command that creates the key: if the process
dies between the two commands, the
counter still carries a window instead of living forever.
### Testing
```
./mvnw -pl shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-token-limiter -am
test
```
`BUILD SUCCESS`, checkstyle clean, `AiTokenLimiterPluginTest` 8/8 including
the new case: the counter is
created with `setIfAbsent(key, 0, window)`, the usage is incremented on it,
and `expire(...)` is **never**
called any more.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]