Workers y colas
src/index.ts es la API y todos los workers a la vez. Lo que corre lo decide la variable de
entorno EXECUTION_MODE, y en docker-compose.yml hay un container por rol.
// src/index.ts, al final
if (hasToWork()) { // EXECUTION_MODE !== "normal"
if (process.env.PAMI_SII_BOT_AUTHORIZATION?.toLowerCase() === "true")
startAutoAuthorizationLoop(); // ← cortocircuita el switch
else
mainWorker(); // WorkerConfigV2.ts
} else {
/* servidor HTTP */
}
Los modos
EXECUTION_MODE | Qué corre | Container |
|---|---|---|
vacío / normal | API HTTP. El primary forkea APP_CORE_LIMIT workers (default = cores) y re-forkea al salir cualquiera | node-app |
bot-publisher | Scraper PAMI: publica a RabbitMQ. Ventana horaria + días hábiles + lock en Redis | bot-publisher |
bot-consumer | Consume de la cola y persiste las autorizaciones | bot-consumer-1..4 |
bot-authorization | Sincronización de autorizaciones. Requiere además PAMI_SII_BOT_AUTHORIZATION=true | bot-authorization |
whatsapp | Procesa las colas de envío y recepción de WhatsApp | — |
emails | Worker de correo | — |
mainWorker() hace process.exit(0) con un warning si el EXECUTION_MODE no matchea ningún case.
El container levanta, no hace nada y se cierra. Si un worker "no hace nada", lo primero que hay que
mirar es el string exacto de la variable.
Bootstrap de un worker
mainWorker() no arranca directo al trabajo: primero inicializa MySQL y Redis y corre las
migraciones de datos (cache de configuración, roles, permisos, tipos de movimiento, migración de
seguridad).
Es decir: levantar un worker escribe datos de configuración. No es un proceso pasivo.
Redis se vacía al arrancar
En el proceso primary, con NODE_ENV !== "dev", el arranque borra todas las claves de Redis. No
guardes ahí nada que tenga que sobrevivir un deploy. Lo que sí vive en Redis:
ACCESSREG-<userId>— el registro de acceso del usuario (rol + permisos + unidades de gestión), con TTLCACHED_USERMETADATA_DB.fetcher_lock— el lock del scraper PAMI.
Colas
src/config/bbdd/QueueConnection.ts envuelve amqplib con auto-reconexión. El broker se configura
con QUEUE_URL. Ante fallos de cola se tira RabbitSyncError.
Consumidores: el bot de PAMI, el worker de WhatsApp (colas de envío y recepción por separado), el de emails y el de notificaciones push.
En docker-compose.yml hay además containers de nginx_proxy, rabbitmq
(imagen rabbitmq:3.11-management, con el panel en el 15672) y socket-server.
cluster.on("exit") llama a fork() incondicionalmente. Un crash-loop no se auto-limita: se ve
como CPU al 100% y logs repetidos, no como el container caído. Si el servicio "está arriba" pero
consume todo el CPU, mirá los logs del worker antes que la infraestructura.