asyncio improvement

This commit is contained in:
2025-11-17 18:43:32 +01:00
parent bdd8674645
commit 036e9da25e
2 changed files with 21 additions and 10 deletions

View File

@@ -20,11 +20,12 @@ class TwitchBot(commands.Bot):
super().__init__( super().__init__(
token=access_token, token=access_token,
# Mandate: Explicitly disable the internal web server.
web_server_adapter=adapter, web_server_adapter=adapter,
eventsub_url=None, # Explicitly disable EventSub eventsub_url=None,
prefix='!', # A prefix is required but won't be used for reading chat prefix='!', # A prefix is required but won't be used for reading chat
initial_channels=[channel_name], initial_channels=[channel_name],
# These are required by twitchio for authentication # These are required by twitchio
client_id=client_id, client_id=client_id,
client_secret=client_secret, client_secret=client_secret,
# The 'bot_id' is the Twitch ID of the user account the bot is running as # The 'bot_id' is the Twitch ID of the user account the bot is running as
@@ -36,7 +37,7 @@ class TwitchBot(commands.Bot):
"""Called once when the bot goes online.""" """Called once when the bot goes online."""
print(f"Listener ready for #{self.channel_name}") print(f"Listener ready for #{self.channel_name}")
async def event_message(self, message): async def event_message(self, message): # Mandate: Type hint removed to prevent import errors.
"""Runs every time a message is sent in chat.""" """Runs every time a message is sent in chat."""
# This is CRITICAL when overriding a listener in commands.Bot # This is CRITICAL when overriding a listener in commands.Bot
# to ensure the bot can still process commands if any are added. # to ensure the bot can still process commands if any are added.

24
main.py
View File

@@ -1,4 +1,5 @@
import os import os
import asyncio
from fastapi import FastAPI, Request, Depends, HTTPException from fastapi import FastAPI, Request, Depends, HTTPException
from starlette.middleware.sessions import SessionMiddleware from starlette.middleware.sessions import SessionMiddleware
from starlette.staticfiles import StaticFiles from starlette.staticfiles import StaticFiles
@@ -23,6 +24,20 @@ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
STATIC_DIR = os.path.join(BASE_DIR, "static") STATIC_DIR = os.path.join(BASE_DIR, "static")
TEMPLATES_DIR = os.path.join(BASE_DIR, "templates") TEMPLATES_DIR = os.path.join(BASE_DIR, "templates")
@asynccontextmanager
async def background_listener_startup(app: FastAPI):
"""A non-blocking task to start listeners after the app has started."""
print("Background task: Starting listeners for all users...")
db = SessionLocal()
users = db.query(models.User).all()
db.close()
for user in users:
# Use try/except to ensure one failing listener doesn't stop others
try:
await app.state.listener_manager.start_listener_for_user(user, app.state.websocket_manager)
except Exception as e:
print(f"ERROR: Failed to start listener for user {user.id} ({user.username}): {e}")
@asynccontextmanager @asynccontextmanager
async def lifespan(app: FastAPI): async def lifespan(app: FastAPI):
# This code runs on startup # This code runs on startup
@@ -32,13 +47,8 @@ async def lifespan(app: FastAPI):
models.Base.metadata.create_all(bind=engine) models.Base.metadata.create_all(bind=engine)
print("Application startup: Database tables created.") print("Application startup: Database tables created.")
# Start listeners for all existing users # Decouple listener startup from the main application startup
db = SessionLocal() asyncio.create_task(background_listener_startup(app))
users = db.query(models.User).all()
db.close()
for user in users:
await app.state.listener_manager.start_listener_for_user(user, app.state.websocket_manager)
yield yield
# This code runs on shutdown # This code runs on shutdown