ADR-0028: etl serve co-locato col worker (avvio unico)
- Stato: Accettata
- Data: 2026-07-23
Contesto
etl serve (ADR-0024) espone i grafi delle pipeline via HTTP, mentre l'esecuzione dei job è demandata a un comando separato etl worker (poller su processes, ADR-0021). I due erano processi/container distinti: stessa immagine Docker (ENTRYPOINT node dist/cli.js), argomento diverso (serve vs worker).
Questo imponeva due avvii per avere una piattaforma funzionante. In sviluppo (dev-desktop.sh → etl:serve) partiva solo il server dei grafi: una run creata dalla UI restava pending perché nessun worker la reclamava — sorgente ricorrente di confusione. L'owner ha deciso di adottare un unico comando di avvio valido in ogni ambiente (dev e produzione/Docker).
Decisione
etl serve avvia, nello stesso processo, sia il server HTTP dei grafi sia il/i worker (un poller per workspace, identico a etl worker):
runServeUntilStopped()(src/cli.ts) caricaloadEtlWorkerConfigs()prima di bindare la porta del server: se l'env del worker è incompleto (NOEVA_WORKSPACE_ID/NOEVA_API_BASE_URL/NOEVA_API_KEY) fa fail-fast conConfigError, invece di lasciare il server in ascolto senza esecutore.- Avvia
startServer()estartWorkers(configs), logga porta/#grafi e #worker/workspace. - Shutdown unico: su SIGTERM/SIGINT ferma server e worker in parallelo (
Promise.allSettled([workers.stopAll(), server.close()])) e poiprocess.exit(0). - Il
DockerfileusaCMD ["serve"]come default: un solo container fa girare tutto.
Il comando etl worker standalone resta disponibile (utile per scalare worker separati), ma non va usato in parallelo a serve nello stesso ambiente.
Conseguenze
- Un solo comando avvia la piattaforma completa in dev e in Docker; in dev le run vengono eseguite senza avviare manualmente il worker.
serveora richiede la config del worker (NOEVA_*): un env incompleto blocca l'avvio. È una scelta deliberata (fail-fast) per non avere un server "monco".- Rischio doppio worker: deployare contemporaneamente un container
servee unoworkerproduce poller duplicati sugli stessi job. Da evitare per convenzione. - Comandi one-off (
list,run <pipeline>) restano invariati sovrascrivendo ilCMD.

