diff --git a/apps/proxy/ts_proxy/channel_status.py b/apps/proxy/ts_proxy/channel_status.py index 33aaa012..b5012b77 100644 --- a/apps/proxy/ts_proxy/channel_status.py +++ b/apps/proxy/ts_proxy/channel_status.py @@ -445,8 +445,9 @@ class ChannelStatus: client_ids = proxy_server.redis_client.smembers(client_set_key) # Remove ghost SET entries before building the client list. + # Pass the already-fetched client_ids to avoid a redundant SMEMBERS. stale_client_ids = ClientManager.remove_ghost_clients( - proxy_server.redis_client, channel_id + proxy_server.redis_client, channel_id, client_ids=client_ids ) if stale_client_ids: client_count = max(0, client_count - len(stale_client_ids)) diff --git a/apps/proxy/ts_proxy/client_manager.py b/apps/proxy/ts_proxy/client_manager.py index e3ae7542..af5fc39d 100644 --- a/apps/proxy/ts_proxy/client_manager.py +++ b/apps/proxy/ts_proxy/client_manager.py @@ -415,14 +415,20 @@ class ClientManager: logger.error(f"Error refreshing client TTL: {e}") @staticmethod - def remove_ghost_clients(redis_client, channel_id): + def remove_ghost_clients(redis_client, channel_id, client_ids=None): """Remove client SET entries whose metadata hash has expired. Returns the list of removed (stale) client IDs, or an empty list if none were found. Uses a pipelined EXISTS check for efficiency. + + Args: + client_ids: Optional pre-fetched result of SMEMBERS for this + channel. Pass this to avoid a redundant SMEMBERS + call when the caller has already fetched it. """ client_set_key = RedisKeys.clients(channel_id) - client_ids = redis_client.smembers(client_set_key) + if client_ids is None: + client_ids = redis_client.smembers(client_set_key) if not client_ids: return [] diff --git a/apps/proxy/ts_proxy/constants.py b/apps/proxy/ts_proxy/constants.py index ca44a278..a13ce88b 100644 --- a/apps/proxy/ts_proxy/constants.py +++ b/apps/proxy/ts_proxy/constants.py @@ -22,7 +22,7 @@ class ChannelState: # States before a channel is fully active. Used by the stream manager # finally block to decide whether a failed stream can write ERROR. - PRE_ACTIVE = [INITIALIZING, CONNECTING, BUFFERING, WAITING_FOR_CLIENTS] + PRE_ACTIVE = frozenset([INITIALIZING, CONNECTING, BUFFERING, WAITING_FOR_CLIENTS]) # Event types class EventType: