/** * Main entry point for unified email worker * * Startup sequence: * 1. Load configuration and domains * 2. Start Prometheus metrics server * 3. Start health check server * 4. Initialize UnifiedWorker * 5. Register signal handlers for graceful shutdown */ import { config, loadDomains } from './config.js'; import { log } from './logger.js'; import { startMetricsServer, type MetricsCollector } from './metrics.js'; import { startHealthServer } from './health.js'; import { UnifiedWorker } from './worker/index.js'; // --------------------------------------------------------------------------- // Banner // --------------------------------------------------------------------------- function printBanner(domains: string[]): void { log('╔══════════════════════════════════════════════════╗'); log('║ Unified Email Worker (TypeScript) ║'); log('║ Version 2.0.0 ║'); log('╚══════════════════════════════════════════════════╝'); log(''); log(`Domains (${domains.length}):`); for (const d of domains) { log(` • ${d}`); } log(''); log(`SMTP: ${config.smtpHost}:${config.smtpPort}`); log(`Internal SMTP: port ${config.internalSmtpPort}`); log(`Poll interval: ${config.pollInterval}s`); log(`Metrics: port ${config.metricsPort}`); log(`Health: port ${config.healthPort}`); log(''); } // --------------------------------------------------------------------------- // Main // --------------------------------------------------------------------------- async function main(): Promise { // 1. Load domains const domains = loadDomains(); if (domains.length === 0) { log('❌ No domains configured. Set DOMAINS env var or provide DOMAINS_FILE.', 'ERROR'); process.exit(1); } printBanner(domains); // 2. Metrics server const metrics: MetricsCollector | null = await startMetricsServer(config.metricsPort); // 3. Unified worker const worker = new UnifiedWorker(domains, metrics); // 4. Health server startHealthServer(config.healthPort, domains, () => worker.getStats()); // 5. Signal handlers let shuttingDown = false; const shutdown = async (signal: string) => { if (shuttingDown) return; shuttingDown = true; log(`\n🛑 Received ${signal}. Shutting down gracefully...`); await worker.stop(); log('👋 Goodbye.'); process.exit(0); }; process.on('SIGINT', () => shutdown('SIGINT')); process.on('SIGTERM', () => shutdown('SIGTERM')); // 6. Start await worker.start(); // Keep alive (event loop stays open due to HTTP servers + SQS polling) log('✅ Worker is running. Press Ctrl+C to stop.'); } // --------------------------------------------------------------------------- main().catch((err) => { log(`💥 Fatal startup error: ${err.message ?? err}`, 'CRITICAL'); log(err.stack ?? '', 'CRITICAL'); process.exit(1); });