From 9ac55f8904bdcf711dcb4b96eba6c3a22b78c48d Mon Sep 17 00:00:00 2001 From: JSC Date: Mon, 7 Jul 2025 21:17:51 +0200 Subject: [PATCH] feat: Enhance stream processing and SocketIO services with app context management --- app/__init__.py | 14 ++++++-- app/services/socketio_service.py | 43 +++-------------------- app/services/stream_processing_service.py | 24 ++++++++----- main.py | 6 +--- 4 files changed, 32 insertions(+), 55 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index 61cccbb..7611fa2 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -85,16 +85,24 @@ def create_app(): # Initialize stream processing service from app.services.stream_processing_service import StreamProcessingService - StreamProcessingService.initialize() + StreamProcessingService.initialize(app) # Initialize music player service from app.services.music_player_service import music_player_service - + music_player_service.app = app # Store app instance for Flask context music_player_service.start_vlc_instance() # Register blueprints - from app.routes import admin, admin_sounds, auth, main, player, soundboard, stream + from app.routes import ( + admin, + admin_sounds, + auth, + main, + player, + soundboard, + stream, + ) app.register_blueprint(main.bp, url_prefix="/api") app.register_blueprint(auth.bp, url_prefix="/api/auth") diff --git a/app/services/socketio_service.py b/app/services/socketio_service.py index 8970c39..d33e0a2 100644 --- a/app/services/socketio_service.py +++ b/app/services/socketio_service.py @@ -9,12 +9,6 @@ from app import socketio logger = logging.getLogger(__name__) -# Add debug print to ensure this module is loaded -print(f"๐Ÿ”ง SocketIO Service: Module loaded, logger level: {logger.level}") -print(f"๐Ÿ”ง SocketIO Service: Effective logger level: {logger.getEffectiveLevel()}") -print(f"๐Ÿ”ง SocketIO Service: Parent logger handlers: {logger.parent.handlers}") -print(f"๐Ÿ”ง SocketIO Service: Logger handlers: {logger.handlers}") - class SocketIOService: """Service for managing SocketIO connections and user rooms.""" @@ -102,33 +96,23 @@ class SocketIOService: @socketio.on("connect") def handle_connect(auth=None): """Handle client connection.""" - print(f"๐Ÿ”Œ CONNECT EVENT HANDLER CALLED: {request.sid}") try: logger.info(f"SocketIO connection established from {request.remote_addr}") logger.info(f"Session ID: {request.sid}") - logger.info(f"Cookies: {request.cookies}") - print(f"๐Ÿ”Œ CONNECT SUCCESS: {request.sid}") except Exception: logger.exception("Error handling SocketIO connection") - print(f"๐Ÿ”Œ CONNECT ERROR: {request.sid}") disconnect() @socketio.on("authenticate") def handle_authenticate(data): """Handle authentication after connection.""" - print(f"๐Ÿ” AUTHENTICATE EVENT HANDLER CALLED: {request.sid}") - logger.info(f"๐Ÿ” SOCKETIO EVENT: authenticate received from {request.sid}") - logger.info(f"๐Ÿ” Auth data: {data}") - logger.info(f"๐Ÿ” Request cookies: {dict(request.cookies)}") - try: user = SocketIOService.get_user_from_socketio() - logger.info(f"๐Ÿ” User lookup result: {user}") if not user: - logger.warning("๐Ÿ” Authentication failed - no user found") + logger.warning("SocketIO authentication failed - no user found") emit("auth_error", {"error": "Authentication failed"}) disconnect() return @@ -139,14 +123,14 @@ def handle_authenticate(data): # Join user-specific room join_room(user_room) - logger.info(f"๐Ÿ” User {user_id} authenticated and joined room {user_room}") + logger.info(f"User {user_id} authenticated and joined room {user_room}") # Send current credits on authentication emit("auth_success", {"user": user}) emit("credits_changed", {"credits": user["credits"]}) except Exception: - logger.exception("๐Ÿ” Error handling SocketIO authentication") + logger.exception("Error handling SocketIO authentication") emit("auth_error", {"error": "Authentication failed"}) disconnect() @@ -154,15 +138,13 @@ def handle_authenticate(data): @socketio.on("test_event") def handle_test_event(data): """Test handler to verify SocketIO events are working.""" - print(f"๐Ÿงช TEST EVENT HANDLER CALLED: {request.sid}") - logger.info(f"๐Ÿงช TEST EVENT received: {data}") + logger.debug(f"Test event received: {data}") emit("test_response", {"message": "Test event received successfully"}) @socketio.on("disconnect") def handle_disconnect(): """Handle client disconnection.""" - print(f"๐Ÿ”Œ DISCONNECT EVENT HANDLER CALLED: {request.sid}") try: user = SocketIOService.get_user_from_socketio() if user: @@ -177,20 +159,3 @@ def handle_disconnect(): # Export the service instance socketio_service = SocketIOService() - -# Debug: Print registered event handlers -try: - print(f"๐Ÿ”ง SocketIO Service: Registered event handlers: {list(socketio.server.handlers.keys())}") - print(f"๐Ÿ”ง SocketIO Service: Namespace handlers: {socketio.server.handlers.get('/', {})}") -except Exception as e: - print(f"๐Ÿ”ง SocketIO Service: Error accessing handlers: {e}") - print(f"๐Ÿ”ง SocketIO Service: SocketIO server: {socketio.server}") - print(f"๐Ÿ”ง SocketIO Service: SocketIO instance: {socketio}") - -# Test manual event registration -@socketio.on("manual_test") -def handle_manual_test(data): - """Manual test handler.""" - print(f"๐Ÿงช MANUAL TEST EVENT: {data}") - -print("๐Ÿ”ง SocketIO Service: Manual test handler registered") diff --git a/app/services/stream_processing_service.py b/app/services/stream_processing_service.py index fe912ec..9344e6b 100644 --- a/app/services/stream_processing_service.py +++ b/app/services/stream_processing_service.py @@ -30,13 +30,18 @@ class StreamProcessingService: os.getenv("STREAM_MAX_CONCURRENT", "2") ) _downloads_dir: str = "sounds/temp" + _app_instance = None # Store the Flask app instance @classmethod - def initialize(cls) -> None: + def initialize(cls, app=None) -> None: """Initialize the stream processing service.""" if cls._is_running: return + # Store the Flask app instance if provided + if app: + cls._app_instance = app + # Create necessary directories os.makedirs(cls._downloads_dir, exist_ok=True) os.makedirs("sounds/stream", exist_ok=True) @@ -83,18 +88,21 @@ class StreamProcessingService: @classmethod def _worker_thread(cls) -> None: """Worker thread for processing streams.""" - from app import create_app - - # Create app context for database operations - app = create_app() - while True: try: # Get stream ID from queue with timeout stream_id = cls._processing_queue.get(timeout=1) - with app.app_context(): - cls._process_stream(stream_id) + # Use the stored app instance for database operations + if cls._app_instance: + with cls._app_instance.app_context(): + cls._process_stream(stream_id) + else: + # Fallback: import create_app if no app instance stored + from app import create_app + app = create_app() + with app.app_context(): + cls._process_stream(stream_id) cls._processing_queue.task_done() diff --git a/main.py b/main.py index cbab741..20e40e8 100644 --- a/main.py +++ b/main.py @@ -6,17 +6,13 @@ from app import create_app, socketio # Load environment variables from .env file load_dotenv() -# Configure logging to show all INFO and DEBUG messages +# Configure logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%H:%M:%S' ) -# Set specific loggers to DEBUG for detailed SocketIO and music player logs -logging.getLogger('app.services.socketio_service').setLevel(logging.DEBUG) -logging.getLogger('app.services.music_player_service').setLevel(logging.INFO) - def main() -> None: """Run the Flask application with SocketIO."""