Merge pull request #446 from g0ldyy/feat/configurable-executor-max-workers

feat: allow configuration of ProcessPoolExecutor max workers with auto-detection and logging
This commit is contained in:
Goldy
2026-01-04 23:48:41 +01:00
committed by GitHub
4 changed files with 15 additions and 5 deletions
+1
View File
@@ -27,6 +27,7 @@ FASTAPI_PORT=8000
FASTAPI_WORKERS=1 # DO NOT change this if you don't know what you are doing. Setting this to -1 will spawn a worker for each CPU core, which can consume several GBs of RAM and cause high CPU usage.
USE_GUNICORN=True # Will use uvicorn if False or if on Windows
GUNICORN_PRELOAD_APP=True # Set to False to start workers without preloading the app (reduces startup cost but requires schema to exist)
EXECUTOR_MAX_WORKERS= # Max workers for ProcessPoolExecutor (handles CPU-intensive tasks like RTN parsing). Leave empty for auto (min(cpu_count, 4)). Increase for higher concurrency on CPU-bound workloads.
# ============================== #
# Playback Settings #
+7 -5
View File
@@ -4,6 +4,8 @@ import os
import signal
from concurrent.futures import ProcessPoolExecutor
from comet.core.models import settings
_mp_context = None
try:
_mp_context = multiprocessing.get_context("forkserver")
@@ -11,19 +13,19 @@ except ValueError:
_mp_context = multiprocessing.get_context("spawn")
app_executor = None
max_workers = settings.EXECUTOR_MAX_WORKERS
if max_workers is None:
cpu_count = os.cpu_count() or 1
max_workers = min(cpu_count, 4)
def worker_initializer():
signal.signal(signal.SIGINT, signal.SIG_IGN)
def setup_executor(max_workers: int | None = None):
def setup_executor():
global app_executor
if max_workers is None:
cpu_count = os.cpu_count() or 1
max_workers = min(cpu_count, 4)
app_executor = ProcessPoolExecutor(
max_workers=max_workers, mp_context=_mp_context, initializer=worker_initializer
)
+6
View File
@@ -5,6 +5,7 @@ import time
from loguru import logger
from comet.core.execution import max_workers
from comet.core.log_levels import (CUSTOM_LOG_LEVELS, STANDARD_LOG_LEVELS,
get_level_info)
@@ -176,6 +177,11 @@ def log_startup_info(settings):
)
logger.log("COMET", f"Gunicorn Preload App: {settings.GUNICORN_PRELOAD_APP}")
logger.log(
"COMET",
f"ProcessPoolExecutor: {max_workers} workers {'(auto)' if settings.EXECUTOR_MAX_WORKERS is None else ''}",
)
if settings.PUBLIC_BASE_URL:
logger.log("COMET", f"Public Base URL: {settings.PUBLIC_BASE_URL}")
+1
View File
@@ -28,6 +28,7 @@ class AppSettings(BaseSettings):
FASTAPI_WORKERS: Optional[int] = 1
USE_GUNICORN: Optional[bool] = True
GUNICORN_PRELOAD_APP: Optional[bool] = True
EXECUTOR_MAX_WORKERS: Optional[int] = None
ADMIN_DASHBOARD_PASSWORD: Optional[str] = "".join(
random.choices(string.ascii_letters + string.digits, k=16)
)