// src/services/queueService.server.ts import { logger } from './logger.server'; import { connection } from './redis.server'; import { flyerQueue, emailQueue, analyticsQueue, weeklyAnalyticsQueue, cleanupQueue, tokenCleanupQueue, } from './queues.server'; // Re-export everything for backward compatibility where possible export { connection } from './redis.server'; export * from './queues.server'; // We do NOT export workers here anymore to prevent side effects. // Consumers needing workers must import from './workers.server'. /** * A function to gracefully shut down all queues and connections. * This is for the API process which only uses queues. * For worker processes, use the gracefulShutdown from workers.server.ts */ export const gracefulShutdown = async (signal: string) => { logger.info(`[Shutdown] Received ${signal}. Closing all queues...`); let exitCode = 0; // Default to success const resources = [ { name: 'flyerQueue', close: () => flyerQueue.close() }, { name: 'emailQueue', close: () => emailQueue.close() }, { name: 'analyticsQueue', close: () => analyticsQueue.close() }, { name: 'cleanupQueue', close: () => cleanupQueue.close() }, { name: 'weeklyAnalyticsQueue', close: () => weeklyAnalyticsQueue.close() }, { name: 'tokenCleanupQueue', close: () => tokenCleanupQueue.close() }, { name: 'redisConnection', close: () => connection.quit() }, ]; const results = await Promise.allSettled(resources.map((r) => r.close())); results.forEach((result, index) => { if (result.status === 'rejected') { logger.error( { err: result.reason, resource: resources[index].name }, `[Shutdown] Error closing resource.`, ); exitCode = 1; // Mark shutdown as failed } }); if (exitCode === 0) { logger.info('[Shutdown] All queues and connections closed successfully.'); } else { logger.warn('[Shutdown] Graceful shutdown completed with errors.'); } process.exit(exitCode); };