From 444676b670af288e44f0cbece284e6c060dc919f Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Mon, 31 Aug 2026 03:44:38 +0200 Subject: [PATCH] fix: invalidate the RedisDict write signature on batch delete RedisDict.set() skips the write when the payload fingerprint matches the last one this process wrote, so a mutation that goes around set() has to clear that fingerprint. The new batch delete did not, leaving a stale fingerprint behind: the next refresh with identical content is treated as already written and silently skipped, so the hash stays empty. Renamed pop_many to delete_many. In a dict emulation pop removes and returns; this returns nothing and cannot without an extra HMGET, so the name promised something it does not do. delete_many matches __delitem__ and the HDEL underneath. Its only call site is the session pool reaper, whose behaviour is unchanged: same fields deleted, same batching, same return. --- backend/open_webui/socket/main.py | 2 +- backend/open_webui/socket/utils.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/socket/main.py b/backend/open_webui/socket/main.py index 5157c3ed36..1168d5945f 100644 --- a/backend/open_webui/socket/main.py +++ b/backend/open_webui/socket/main.py @@ -206,7 +206,7 @@ async def periodic_session_pool_cleanup(): if expired: log.warning('Reaping %d orphaned session(s) from the session pool', len(expired)) if WEBSOCKET_MANAGER == 'redis': - SESSION_POOL.pop_many(*expired) + SESSION_POOL.delete_many(*expired) else: for sid in expired: SESSION_POOL.pop(sid, None) diff --git a/backend/open_webui/socket/utils.py b/backend/open_webui/socket/utils.py index 3e1479bde0..323735f6f1 100644 --- a/backend/open_webui/socket/utils.py +++ b/backend/open_webui/socket/utils.py @@ -115,10 +115,11 @@ class RedisDict: if cursor == 0: break - def pop_many(self, *keys): + def delete_many(self, *keys): """Delete fields in one HDEL; no keys is a no-op (HDEL rejects an empty field list).""" if keys: self.redis.hdel(self.name, *keys) + self._last_signature = None def set(self, mapping: dict): if not mapping: