Update setup_server.py

This commit is contained in:
tecnotel 2026-05-04 21:03:48 +02:00
parent 42ec00bb40
commit 5dddd82240
1 changed files with 43 additions and 11 deletions

View File

@ -559,32 +559,64 @@ def _write_nginx_conf(conf):
def _write_services(): def _write_services():
venv_py = str(APP_DIR / "backend/venv/bin/python3") """Genera le 4 unit systemd ARGOS in versione Gunicorn.
Mappatura service wsgi target:
- argos-backend : argos_backend:app (no wrapper, app a top-level)
- argos-sync : argos_sync_wsgi:app (wrapper avvia main_loop)
- argos-ops : argos_ops_wsgi:app (wrapper avvia main_loop)
- argos-analytics : argos_analytics_wsgi:app (wrapper avvia _scheduler_loop)
Vincolo critico: workers=1 obbligatorio per sync/ops/analytics.
Hanno scheduler in-memory + thread daemon che, con N worker, sarebbero
duplicati N volte (job doppi, file lock contention, race su SQLite).
Backend e' API stateless: 2 worker sync per migliorare throughput.
Gli altri usano gthread (threads=4) per servire API mentre lo scheduler
interno gira nel thread daemon.
Aggiornato 04/05/2026: migrazione da Flask dev server a Gunicorn 25.3+.
"""
venv_bin = str(APP_DIR / "backend/venv/bin")
backend_dir = str(APP_DIR / "backend") backend_dir = str(APP_DIR / "backend")
services_dir = str(APP_DIR / "backend/services")
# (wsgi_target, workers, threads, timeout_sec, port, description)
services = { services = {
"backend": ("services/argos_backend.py", "Backend API"), "backend": ("argos_backend:app", 2, 1, 120, 8080, "Backend API"),
"sync": ("services/argos_sync.py", "Sync Daemon"), "sync": ("argos_sync_wsgi:app", 1, 4, 600, 8081, "Sync Daemon"),
"ops": ("services/argos_ops.py", "Ops Daemon"), "ops": ("argos_ops_wsgi:app", 1, 4, 600, 8082, "Ops Daemon"),
"analytics": ("services/argos_analytics.py", "Analytics Daemon"), "analytics": ("argos_analytics_wsgi:app", 1, 4, 300, 8083, "Analytics Daemon"),
} }
for svc, (script, desc) in services.items(): for svc, (wsgi, workers, threads, timeout, port, desc) in services.items():
# Solo i servizi con threads>1 usano gthread; backend e' sync con 2 worker.
threads_line = f" --threads {threads} \\\n" if threads > 1 else ""
unit = f"""[Unit] unit = f"""[Unit]
Description=ARGOS {desc} Description=ARGOS {desc} (Gunicorn)
After=network.target After=network.target
[Service] [Service]
Type=simple Type=simple
User={APP_USER} User={APP_USER}
Group={APP_USER} Group={APP_USER}
WorkingDirectory={backend_dir} WorkingDirectory={services_dir}
Environment=PYTHONPATH={backend_dir} Environment=PYTHONPATH={backend_dir}:{services_dir}
Environment=CONFIG_FILE={CONFIG_DIR}/argos.json Environment=CONFIG_FILE={CONFIG_DIR}/argos.json
Environment=INTEGRATIONS_FILE={CONFIG_DIR}/integrations.json Environment=INTEGRATIONS_FILE={CONFIG_DIR}/integrations.json
Environment=DATA_DIR={DATA_DIR} Environment=DATA_DIR={DATA_DIR}
Environment=FEEDS_DIR={FEEDS_DIR} Environment=FEEDS_DIR={FEEDS_DIR}
Environment=LOGS_DIR={LOGS_DIR} Environment=LOGS_DIR={LOGS_DIR}
ExecStart={venv_py} {backend_dir}/{script} ExecStart={venv_bin}/gunicorn {wsgi} \\
--workers {workers} \\
{threads_line} --bind 127.0.0.1:{port} \\
--timeout {timeout} \\
--graceful-timeout 30 \\
--keep-alive 5 \\
--access-logfile - \\
--error-logfile - \\
--log-level info \\
--capture-output
Restart=always Restart=always
RestartSec=5 RestartSec=5
StandardOutput=journal StandardOutput=journal