fix(worker): close all Queue singletons + promotion intervals on SIGTERM (issue #94 bugs 4, 7, 10)
This commit is contained in:
parent
6eb98d866b
commit
bacdb9f49c
1 changed files with 24 additions and 4 deletions
|
|
@ -1,9 +1,9 @@
|
|||
import 'dotenv/config';
|
||||
import { Worker } from 'bullmq';
|
||||
import { proxyWorker } from './workers/proxy.js';
|
||||
import { proxyWorker, thumbnailQueue as proxyThumbnailQueue } from './workers/proxy.js';
|
||||
import { thumbnailWorker } from './workers/thumbnail.js';
|
||||
import { conformWorker } from './workers/conform.js';
|
||||
import { youtubeImportWorker } from './workers/youtube-import.js';
|
||||
import { youtubeImportWorker, proxyQueue as youtubeProxyQueue } from './workers/youtube-import.js';
|
||||
import { trimWorker } from './workers/trimWorker.js';
|
||||
import { startPromotionWorker } from './workers/promotion.js';
|
||||
|
||||
|
|
@ -77,7 +77,9 @@ const workers = [
|
|||
|
||||
console.log(`Concurrency: proxy=${PROXY_CONCURRENCY} thumbnail=${THUMBNAIL_CONCURRENCY} conform=${CONFORM_CONCURRENCY} trim=${TRIM_CONCURRENCY} import=1`);
|
||||
|
||||
startPromotionWorker();
|
||||
// BUG FIX #4: startPromotionWorker() now returns a shutdown function that
|
||||
// clears the poll intervals and closes the promotion proxyQueue singleton.
|
||||
const stopPromotionWorker = startPromotionWorker();
|
||||
|
||||
console.log('Wild Dragon Worker Service started');
|
||||
console.log(`Redis: ${redisOptions.host}:${redisOptions.port}`);
|
||||
|
|
@ -86,6 +88,24 @@ console.log('Background scans: promotion (growing-files → S3)');
|
|||
|
||||
process.on('SIGTERM', async () => {
|
||||
console.log('SIGTERM received, shutting down...');
|
||||
await Promise.all(workers.map(w => w.close()));
|
||||
|
||||
// BUG FIX #4 + #10: Close all BullMQ Workers AND all Queue client instances
|
||||
// on SIGTERM. Workers process jobs; Queues dispatch them. Both hold open
|
||||
// Redis connections that keep the event loop alive after workers are closed,
|
||||
// causing the process to hang indefinitely unless process.exit() is called.
|
||||
// Explicitly closing every Queue allows the event loop to drain naturally.
|
||||
await Promise.all([
|
||||
// Close all Worker instances (stops accepting new jobs, waits for active)
|
||||
...workers.map(w => w.close()),
|
||||
// BUG FIX #7: Close the Queue singletons from worker modules.
|
||||
// proxyThumbnailQueue: thumbnailQueue in proxy.js (dispatches thumbnail jobs)
|
||||
// youtubeProxyQueue: proxyQueue in youtube-import.js (dispatches proxy jobs)
|
||||
proxyThumbnailQueue.close().catch(() => {}),
|
||||
youtubeProxyQueue.close().catch(() => {}),
|
||||
// BUG FIX #4: Stop the promotion worker intervals and close its proxyQueue
|
||||
stopPromotionWorker(),
|
||||
]);
|
||||
|
||||
console.log('All workers and queues closed');
|
||||
process.exit(0);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue