2025-06-17 13:20:44 +09:30
# websocket_server/redis_utils.py
import threading
import traceback
import time
from websocket_server.config import get_redis_client
from websocket_server.task_assigner import assign_task_to_worker
from websocket_server.worker_manager import notify_worker_disconnect
import logging
2025-10-27 08:42:45 +10:30
from websocket_server.config import ENABLE_TASK_ASSIGNMENT_DEBUG
2025-06-17 13:20:44 +09:30
logger = logging . getLogger ( "websocket_server" )
# Shared state
worker_dispatch_flags = {}
thread_stop_flags = {}
def redis_subscribe ( worker_id ):
"""
Redis Pub/Sub monitor for a specific worker.
Subscribes to worker status and queue keys and sets dispatch flags accordingly.
"""
2025-06-17 14:16:52 +09:30
2025-06-17 13:20:44 +09:30
redis_client = get_redis_client ()
2025-07-28 00:53:37 +09:30
redis_client . config_set ( "notify-keyspace-events" , "KEA" )
logger . debug ( f "Total available in pool: { len ( redis_client . connection_pool . _available_connections ) } " )
2025-06-17 13:20:44 +09:30
pubsub = redis_client . pubsub ()
channels = [
2025-07-28 00:53:37 +09:30
f "__keyspace@2__:worker_status_ { worker_id } " , #TODO - The number 2 here is important, it's the Redis DB number which must align with the resid URL in config.py!
f "__keyspace@2__:worker_queue_ { worker_id } "
2025-06-17 13:20:44 +09:30
]
2025-08-15 14:43:50 +09:30
2025-06-17 13:20:44 +09:30
try :
pubsub . psubscribe ( channels )
logger . info ( f "Subscribed to Redis keyspace events: { channels } " )
while not thread_stop_flags . get ( worker_id , False ):
message = pubsub . get_message ( timeout = 1.0 )
if message and message [ "type" ] in [ "pmessage" , "message" ]:
current_status = redis_client . get ( f "worker_status_ { worker_id } " )
2025-10-27 08:42:45 +10:30
if ENABLE_TASK_ASSIGNMENT_DEBUG :
logger . debug ( f "[ { worker_id } ] Current Redis status: { current_status } " )
2025-06-17 13:20:44 +09:30
if current_status and current_status . lower () == "idle" :
if redis_client . get ( f "worker_queue_ { worker_id } " ) . lower () == "true" :
2025-10-27 08:42:45 +10:30
if ENABLE_TASK_ASSIGNMENT_DEBUG :
logger . debug ( f "[ { worker_id } ] Queue is true, setting dispatch flag" )
2025-06-17 13:20:44 +09:30
worker_dispatch_flags [ worker_id ] = True
else :
2025-10-27 08:42:45 +10:30
if ENABLE_TASK_ASSIGNMENT_DEBUG :
logger . debug ( f "[ { worker_id } ] Queue false, no dispatch needed" )
2025-06-17 13:20:44 +09:30
else :
2025-10-27 08:42:45 +10:30
if ENABLE_TASK_ASSIGNMENT_DEBUG :
logger . debug ( f "[ { worker_id } ] Status is not idle, skipping" )
2025-06-17 13:20:44 +09:30
logger . warning ( f "[ { worker_id } ] Redis pub/sub loop exited, disconnecting" )
notify_worker_disconnect ( worker_id )
except Exception as e :
error_details = traceback . format_exc ()
logger . error ( f "[ { worker_id } ] Redis pub/sub error: { e } \n { error_details } " )
finally :
pubsub . close ()