mirror of
https://github.com/suitenumerique/meet.git
synced 2026-08-29 19:57:14 +00:00
⚡️(backend) replace blocking Redis KEYS with cursor-based SCAN
`cache.keys()` runs Redis `KEYS`, a full-keyspace scan on Redis's single thread that blocks everything else, including session reads in the same cache. Its cost scales with total keys, not matches, and some managed providers disable `KEYS` entirely. The trusted-lobby feature made this urgent: the waiting-list endpoint scanned on every poll, and its polling audience grows from a few admins to potentially every authenticated participant. Switch to cursor-based `SCAN` via two `core.utils` helpers, deleting in bounded batches so cleanup of a large room cannot block either. A single seam also lets us forbid raw `cache.keys()` going forward. `SCAN` still iterates the keyspace incrementally on the polled path. If monitoring flags it, the follow-up is a per-room set index — out of scope here since it changes the lobby storage model.
This commit is contained in:
committed by
aleb_the_flash
parent
943b81676b
commit
76a24d4787
@@ -270,7 +270,7 @@ class LobbyService:
|
||||
"""List all waiting participants for a room."""
|
||||
|
||||
pattern = self._get_cache_key(room_id, "*")
|
||||
keys = cache.keys(pattern)
|
||||
keys = list(cache.iter_keys(pattern, itersize=utils.CACHE_SCAN_ITERSIZE))
|
||||
|
||||
if not keys:
|
||||
return []
|
||||
@@ -345,13 +345,9 @@ class LobbyService:
|
||||
def clear_room_cache(self, room_id: UUID) -> None:
|
||||
"""Clear all participant entries from the cache for a specific room."""
|
||||
|
||||
pattern = self._get_cache_key(room_id, "*")
|
||||
keys = cache.keys(pattern)
|
||||
|
||||
if not keys:
|
||||
return
|
||||
|
||||
cache.delete_many(keys)
|
||||
cache.delete_pattern(
|
||||
self._get_cache_key(room_id, "*"), itersize=utils.CACHE_SCAN_ITERSIZE
|
||||
)
|
||||
|
||||
def clear_participant_cache(self, room_id: UUID, participant_id: str) -> None:
|
||||
"""Clear a given participant entry from the cache for a specific room."""
|
||||
|
||||
@@ -18,6 +18,8 @@ from uuid import UUID
|
||||
from django.conf import settings
|
||||
from django.core.cache import cache
|
||||
|
||||
from core.utils import CACHE_SCAN_ITERSIZE
|
||||
|
||||
|
||||
class PresenceCache:
|
||||
"""Store and invalidate (room, identity) presence entries."""
|
||||
@@ -45,6 +47,6 @@ class PresenceCache:
|
||||
|
||||
def clear_room(self, room_id: UUID | str) -> None:
|
||||
"""Forget presence for every participant of a room (on room_finished)."""
|
||||
keys = cache.keys(self._get_cache_key(room_id, "*"))
|
||||
if keys:
|
||||
cache.delete_many(keys)
|
||||
cache.delete_pattern(
|
||||
self._get_cache_key(room_id, "*"), itersize=CACHE_SCAN_ITERSIZE
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user