HY-love-sleep opened a new issue, #7163:
URL: https://github.com/apache/shenyu/issues/7163

   ### Context
   
   Follow-ups raised in the review of #7157, which added the lifecycle end to 
`RedisConnectionFactory` and
   made the four sites that replace a redis client release the one they 
replace. All three items below are
   the same story from different angles: a client that is replaced or removed 
stays reachable, or is never
   released at all.
   
   ### 1. `CachePluginDataHandler`: the previous cache is destroyed before the 
new one is installed
   
   `handlerPlugin(...)` currently does:
   
   ```java
   Singleton.INST.single(CacheConfig.class, cacheConfig);
   this.closeCacheIfNeed();                                                  // 
destroys the previous cache here
   final ICacheBuilder cacheBuilder = ExtensionLoader...getJoin(...);
   Singleton.INST.single(ICache.class, cacheBuilder.builderCache(config));   // 
installs the new one later
   ```
   
   and `closeCacheIfNeed()` only closes the previous cache — it never clears 
`ICache.class` from
   `Singleton`. So between those two statements `CacheUtils.getCache()` still 
hands out the cache whose
   connection factory was just destroyed, and a request that lands in that 
window fails. Before #7157 the
   window was survivable, because `RedisCache.close()` only returned borrowed 
connections to the pool.
   
   Fix: install the new cache first, then close the previous one — the order 
the three handlers changed by
   #7157 already use. Evicting `ICache.class` instead is not possible today: 
`Singleton` has no removal API,
   and the readers of `CacheUtils.getCache()` do not null-check it.
   
   ### 2. `AiTokenLimiterPluginHandler` and `RateLimiterPluginDataHandler` have 
no `removePlugin`
   
   Both keep their client in a process-wide place — a `CommonHandleCache` and 
`Singleton.INST` respectively —
   so when the plugin is removed or disabled, the client, its connection pool 
and its Netty event loops stay
   alive for the rest of the process lifetime. `SensitiveWordPluginDataHandler` 
releases its client in
   `removePlugin` (added by #7157), and `destroyQuietly(...)` makes this a 
couple of lines per handler.
   
   - **`AiTokenLimiterPluginHandler`** is straightforward: destroy the cached 
client and clear the two caches.
   - **`RateLimiterPluginDataHandler`** needs an eviction point first. 
`Singleton` has no removal API, so
     destroying the client in `removePlugin` while leaving the entry behind 
would make the next
     `handlerPlugin` treat the destroyed client as valid (it rebuilds only when 
`RedisConfigProperties`
     differs) and hand it to `RedisRateLimiter` / 
`ConcurrentRateLimiterAlgorithm`, which do not null-check
     `Singleton.INST.get(ReactiveRedisTemplate.class)`. Either `Singleton` 
gains a removal API
     (`remove(Class)`), or this handler keeps its client in a 
`CommonHandleCache` like the others.
   
   ### 3. Note only: `RedisConnectionFactory.destroy()` has no production 
caller yet
   
   The instance `destroy()` belongs to the wrapper that owns the pool, but 
every call site holds the reactive
   template, so it passes the inner `LettuceConnectionFactory` to 
`destroyQuietly(...)` — which is enough,
   the lettuce factory has implemented `DisposableBean` all along. For the 
wrapper to "earn its keep", the
   call sites would have to keep the `RedisConnectionFactory` instead of 
extracting the lettuce factory from
   it. No behaviour change involved; recorded for completeness.
   
   ### Plan
   
   I am happy to take 1 and the `AiTokenLimiterPluginHandler` half of 2 in a 
follow-up PR. For the rate
   limiter I would rather hear which eviction point you prefer before writing 
it, @Aias00 — adding a
   removal API to `Singleton` (used across plugins) is a bigger decision than 
the fix itself.
   


-- 
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]

Reply via email to