perf: faster filter lookups on chat requests when Redis is enabled (#33668)

With Redis enabled, each chat request and each title or tag generation looks up which pipeline filters apply, and every lookup parsed the full model list stored in Redis from scratch. Each worker now keeps the parsed list and parses it again only when the model list changes. The lookup returns the same filters as before, at the cost of about 3 MB of memory per worker for 1000 models.

Measured per lookup against a local Redis; the larger list size in each pair comes from models with profile images:

| Models | Model list size | Before | After |
| --- | --- | --- | --- |
| 200 | 0.17 MB | 0.42 ms | 0.05 ms |
| 200 | 2.2 MB | 1.16 ms | 0.05 ms |
| 1000 | 0.83 MB | 2.43 ms | 0.06 ms |
| 1000 | 11 MB | 6.21 ms | 0.10 ms |
This commit is contained in:
Classic298
2026-11-04 05:06:15 +09:00
committed by GitHub
parent f36807a55f
commit d00a02ff23
+7 -1
View File
@@ -214,12 +214,14 @@ class CachedRedisDict(RedisDict):
super().__init__(name, redis_url, redis_sentinels, redis_cluster, cache_set_signature=True)
self._cache: dict = {}
self._cached_signature: str | None = None
self._cached_values: list | None = None
def _refresh_cache(self) -> dict:
stored_signature = self.redis.get(self._signature_name)
if stored_signature is None or stored_signature != self._cached_signature:
self._cache = self.redis.hgetall(self.name)
self._cached_signature = stored_signature
self._cached_values = None
return self._cache
def __getitem__(self, key):
@@ -238,7 +240,11 @@ class CachedRedisDict(RedisDict):
return list(self._refresh_cache().keys())
def values(self):
return [JSONCodec.loads(v) for v in self._refresh_cache().values()]
cache = self._refresh_cache()
# Decoded once per signature; callers share these dicts read-only.
if self._cached_values is None:
self._cached_values = [JSONCodec.loads(v) for v in cache.values()]
return list(self._cached_values)
def items(self):
return [(k, JSONCodec.loads(v)) for k, v in self._refresh_cache().items()]