From cd7dde44776b59a620b71281d6a3d3ae1abe8316 Mon Sep 17 00:00:00 2001 From: dgtlmoon Date: Mon, 2 Jun 2025 18:32:10 +0200 Subject: [PATCH] gevent/thread type cleanups --- changedetectionio/realtime/socket_server.py | 28 ++++++++++----------- requirements.txt | 4 ++- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/changedetectionio/realtime/socket_server.py b/changedetectionio/realtime/socket_server.py index ef72130ba..fb70e5857 100644 --- a/changedetectionio/realtime/socket_server.py +++ b/changedetectionio/realtime/socket_server.py @@ -220,27 +220,27 @@ def init_socketio(app, datastore): system = platform.system().lower() python_version = sys.version_info - # Check for manual override via environment variable - force_threading = strtobool(os.getenv('SOCKETIO_FORCE_THREADING', 'False')) - force_gevent = strtobool(os.getenv('SOCKETIO_FORCE_GEVENT', 'False')) + # Check for SocketIO mode configuration via environment variable + # Default is 'threading' for best cross-platform compatibility + socketio_mode = os.getenv('SOCKETIO_MODE', 'threading').lower() - if force_threading: - # Manual override to threading mode - async_mode = 'threading' - logger.info(f"SOCKETIO_FORCE_THREADING=True: Using {async_mode} mode for Socket.IO (manual override)") - elif force_gevent: - # Manual override to gevent mode for testing + if socketio_mode == 'gevent': + # Use gevent mode (higher concurrency but platform limitations) try: import gevent async_mode = 'gevent' - logger.info(f"SOCKETIO_FORCE_GEVENT=True: Using {async_mode} mode for Socket.IO (manual override)") + logger.info(f"SOCKETIO_MODE=gevent: Using {async_mode} mode for Socket.IO") except ImportError: async_mode = 'threading' - logger.warning(f"SOCKETIO_FORCE_GEVENT=True but gevent not available, falling back to {async_mode} mode") - else: - # Use threading mode for all platforms - simpler, more reliable, and future-proof + logger.warning(f"SOCKETIO_MODE=gevent but gevent not available, falling back to {async_mode} mode") + elif socketio_mode == 'threading': + # Use threading mode (default - best compatibility) async_mode = 'threading' - logger.info(f"Platform: {system}, Python: {python_version.major}.{python_version.minor} - Using {async_mode} mode for Socket.IO") + logger.info(f"SOCKETIO_MODE=threading: Using {async_mode} mode for Socket.IO") + else: + # Invalid mode specified, use default + async_mode = 'threading' + logger.warning(f"Invalid SOCKETIO_MODE='{socketio_mode}', using default {async_mode} mode for Socket.IO") # Log platform info for debugging logger.info(f"Platform: {system}, Python: {python_version.major}.{python_version.minor}, Socket.IO mode: {async_mode}") diff --git a/requirements.txt b/requirements.txt index ea69b1557..145352459 100644 --- a/requirements.txt +++ b/requirements.txt @@ -100,7 +100,9 @@ levenshtein # Needed for > 3.10, https://github.com/microsoft/playwright-python/issues/2096 greenlet >= 3.0.3 -# Used for realtime socketio mode (so its a different driver to eventlet/threading not to interfere with playwright) +# Optional: Used for high-concurrency SocketIO mode (via SOCKETIO_MODE=gevent) +# Note: gevent has cross-platform limitations (Windows 1024 socket limit, macOS ARM build issues) +# Default SOCKETIO_MODE=threading is recommended for better compatibility gevent # Pinned or it causes problems with flask_expects_json which seems unmaintained