From 1650f9343e2087b5214e1d8fac8d1380206802a0 Mon Sep 17 00:00:00 2001 From: ramforth Date: Tue, 18 Nov 2025 01:48:36 +0100 Subject: [PATCH] ruining a good night's sleep --- listener_manager.py | 47 +++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/listener_manager.py b/listener_manager.py index 83aa36a..fd3952b 100644 --- a/listener_manager.py +++ b/listener_manager.py @@ -9,7 +9,7 @@ class ListenerManager: def __init__(self): # This dictionary will hold our running listener tasks. # The key will be the user_id and the value will be the asyncio.Task. - self.active_listeners: Dict[int, asyncio.Task] = {} + self.active_listeners: Dict[int, Dict] = {} print("ListenerManager initialized.") async def start_listener_for_user(self, user, websocket_manager): @@ -27,29 +27,42 @@ class ListenerManager: print(f"Starting listener for user {user.id} ({user.username})...") - tokens = security.decrypt_tokens(user.encrypted_tokens) - access_token = tokens['access_token'] - bot = TwitchBot( - access_token=access_token, - channel_name=user.username, - client_id=settings.TWITCH_CLIENT_ID, - client_secret=settings.TWITCH_CLIENT_SECRET, - websocket_manager=websocket_manager, - db_user_id=user.id - ) - # We now call our custom start() method in the TwitchBot class, - # which gives us direct control over the connection process. - task = asyncio.create_task(bot.start()) - self.active_listeners[user.id] = task + try: + tokens = security.decrypt_tokens(user.encrypted_tokens) + access_token = tokens['access_token'] + + bot = TwitchBot( + access_token=access_token, + channel_name=user.username, + client_id=settings.TWITCH_CLIENT_ID, + client_secret=settings.TWITCH_CLIENT_SECRET, + websocket_manager=websocket_manager, + db_user_id=user.id + ) + + task = asyncio.create_task(bot.start()) + # Store both the task and the bot instance for graceful shutdown + self.active_listeners[user.id] = {"task": task, "bot": bot} + except Exception as e: + # This will catch errors during bot instantiation (e.g., bad token) + print(f"ERROR: Failed to instantiate or start listener for user {user.id}: {e}") async def stop_listener_for_user(self, user_id: int): """Stops a chat listener for a given user.""" if user_id not in self.active_listeners: print(f"No active listener found for user {user_id}.") return - + print(f"Stopping listener for user {user_id}...") - task = self.active_listeners.pop(user_id) + listener_info = self.active_listeners.pop(user_id) + task = listener_info["task"] + bot = listener_info["bot"] + + # Gracefully close the bot's connection + if bot and not bot.is_closed(): + await bot.close() + + # Cancel the asyncio task task.cancel() try: await task