From c246720b06380fdab3895eab1bf79c19d5b0eede Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sun, 6 Oct 2024 21:09:23 +0530 Subject: [PATCH 01/20] feat: use workflowQueue --- server/src/routes/storage.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/server/src/routes/storage.ts b/server/src/routes/storage.ts index 3ce853b1..1b43de7b 100644 --- a/server/src/routes/storage.ts +++ b/server/src/routes/storage.ts @@ -10,7 +10,7 @@ import { chromium } from "playwright"; import { browserPool } from "../server"; import fs from "fs"; import { uuid } from "uuidv4"; -// import { workflowQueue } from '../workflow-management/scheduler'; +import { workflowQueue } from '../workflow-management/scheduler'; import moment from 'moment-timezone'; import cron from 'node-cron'; import { googleSheetUpdateTasks, processGoogleSheetUpdates } from '../workflow-management/integrations/gsheet'; @@ -280,16 +280,16 @@ router.put('/schedule/:fileName/', requireSignIn, async (req, res) => { const runId = uuid(); - // await workflowQueue.add( - // 'run workflow', - // { fileName, runId }, - // { - // repeat: { - // pattern: cronExpression, - // tz: timezone - // } - // } - // ); + await workflowQueue.add( + 'run workflow', + { fileName, runId }, + { + repeat: { + pattern: cronExpression, + tz: timezone + } + } + ); res.status(200).json({ message: 'success', From f3964ceffa4a1e26338e981ec513dbc2ab4434a1 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Mon, 7 Oct 2024 01:16:49 +0530 Subject: [PATCH 02/20] feat: move bullmq worker --- server/src/worker.ts | 61 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 server/src/worker.ts diff --git a/server/src/worker.ts b/server/src/worker.ts new file mode 100644 index 00000000..da923763 --- /dev/null +++ b/server/src/worker.ts @@ -0,0 +1,61 @@ +import fs from "fs"; +import { uuid } from "uuidv4"; +import { chromium } from "playwright"; +import { io, Socket } from "socket.io-client"; +import { Queue, Worker } from 'bullmq'; +import IORedis from 'ioredis'; +import { readFile, saveFile } from "../storage"; +import { createRemoteBrowserForRun, destroyRemoteBrowser } from '../../browser-management/controller'; +import logger from '../../logger'; +import { browserPool } from "../../server"; +import { googleSheetUpdateTasks, processGoogleSheetUpdates } from "../integrations/gsheet"; + +const connection = new IORedis({ + host: 'localhost', + port: 6379, + maxRetriesPerRequest: null, +}); + +connection.on('connect', () => { + console.log('Connected to Redis!'); +}); + +connection.on('error', (err) => { + console.error('Redis connection error:', err); +}); + +const workflowQueue = new Queue('workflow', { connection }); + +export const worker = new Worker('workflow', async job => { + const { fileName, runId } = job.data; + try { + const result = await handleRunRecording(fileName, runId); + return result; + } catch (error) { + logger.error('Error running workflow:', error); + throw error; + } +}, { connection }); + +worker.on('completed', async (job: any) => { + logger.log(`info`, `Job ${job.id} completed for ${job.data.fileName}_${job.data.runId}`); + + await worker.close(); + await workflowQueue.close(); + logger.log(`info`, `Worker and queue have been closed.`); +}); + +worker.on('failed', async (job: any, err) => { + logger.log(`error`, `Job ${job.id} failed for ${job.data.fileName}_${job.data.runId}:`, err); + + await worker.close(); + await workflowQueue.close(); + logger.log(`info`, `Worker and queue have been closed after failure.`); +}); + +async function jobCounts() { + const jobCounts = await workflowQueue.getJobCounts(); + console.log('Jobs:', jobCounts); +} + +jobCounts(); \ No newline at end of file From fef6811387b8c8b98f07080015230919fe90d4bb Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Mon, 7 Oct 2024 01:19:04 +0530 Subject: [PATCH 03/20] fix: broken imports --- server/src/worker.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server/src/worker.ts b/server/src/worker.ts index da923763..98c9f0e7 100644 --- a/server/src/worker.ts +++ b/server/src/worker.ts @@ -4,11 +4,11 @@ import { chromium } from "playwright"; import { io, Socket } from "socket.io-client"; import { Queue, Worker } from 'bullmq'; import IORedis from 'ioredis'; -import { readFile, saveFile } from "../storage"; -import { createRemoteBrowserForRun, destroyRemoteBrowser } from '../../browser-management/controller'; -import logger from '../../logger'; -import { browserPool } from "../../server"; -import { googleSheetUpdateTasks, processGoogleSheetUpdates } from "../integrations/gsheet"; +import { readFile, saveFile } from "./workflow-management/storage"; +import { createRemoteBrowserForRun, destroyRemoteBrowser } from './browser-management/controller'; +import logger from './logger'; +import { browserPool } from "./server"; +import { googleSheetUpdateTasks, processGoogleSheetUpdates } from "./workflow-management/integrations/gsheet"; const connection = new IORedis({ host: 'localhost', From 4dcfda851a547bbff7faaba7de8faca09e439c14 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Mon, 7 Oct 2024 01:19:35 +0530 Subject: [PATCH 04/20] feat: export workerQueue --- server/src/worker.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/src/worker.ts b/server/src/worker.ts index 98c9f0e7..1177383d 100644 --- a/server/src/worker.ts +++ b/server/src/worker.ts @@ -58,4 +58,6 @@ async function jobCounts() { console.log('Jobs:', jobCounts); } -jobCounts(); \ No newline at end of file +jobCounts(); + +export { workflowQueue, runWorkflow }; \ No newline at end of file From 36133f484cda178e1282207a960ac863649885d9 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Mon, 7 Oct 2024 01:20:24 +0530 Subject: [PATCH 05/20] fix: -rm duplicate export for worker --- server/src/worker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/worker.ts b/server/src/worker.ts index 1177383d..cd88a6ff 100644 --- a/server/src/worker.ts +++ b/server/src/worker.ts @@ -26,7 +26,7 @@ connection.on('error', (err) => { const workflowQueue = new Queue('workflow', { connection }); -export const worker = new Worker('workflow', async job => { +const worker = new Worker('workflow', async job => { const { fileName, runId } = job.data; try { const result = await handleRunRecording(fileName, runId); @@ -60,4 +60,4 @@ async function jobCounts() { jobCounts(); -export { workflowQueue, runWorkflow }; \ No newline at end of file +export { workflowQueue, worker }; \ No newline at end of file From 48c0145ddc4b4b162b9532e925e9132756cd5f57 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Mon, 7 Oct 2024 01:21:19 +0530 Subject: [PATCH 06/20] feat: import handleRunRecording --- server/src/worker.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/server/src/worker.ts b/server/src/worker.ts index cd88a6ff..a17d3bde 100644 --- a/server/src/worker.ts +++ b/server/src/worker.ts @@ -9,6 +9,7 @@ import { createRemoteBrowserForRun, destroyRemoteBrowser } from './browser-manag import logger from './logger'; import { browserPool } from "./server"; import { googleSheetUpdateTasks, processGoogleSheetUpdates } from "./workflow-management/integrations/gsheet"; +import { handleRunRecording } from "./workflow-management/scheduler"; const connection = new IORedis({ host: 'localhost', From 07894b44e2e39b11db8de1647c8d3d2ef1be439e Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Mon, 7 Oct 2024 01:21:39 +0530 Subject: [PATCH 07/20] chore: prettier --- server/src/worker.ts | 46 ++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/server/src/worker.ts b/server/src/worker.ts index a17d3bde..a45e525f 100644 --- a/server/src/worker.ts +++ b/server/src/worker.ts @@ -12,51 +12,51 @@ import { googleSheetUpdateTasks, processGoogleSheetUpdates } from "./workflow-ma import { handleRunRecording } from "./workflow-management/scheduler"; const connection = new IORedis({ - host: 'localhost', - port: 6379, - maxRetriesPerRequest: null, + host: 'localhost', + port: 6379, + maxRetriesPerRequest: null, }); connection.on('connect', () => { - console.log('Connected to Redis!'); + console.log('Connected to Redis!'); }); connection.on('error', (err) => { - console.error('Redis connection error:', err); + console.error('Redis connection error:', err); }); const workflowQueue = new Queue('workflow', { connection }); const worker = new Worker('workflow', async job => { - const { fileName, runId } = job.data; - try { - const result = await handleRunRecording(fileName, runId); - return result; - } catch (error) { - logger.error('Error running workflow:', error); - throw error; - } + const { fileName, runId } = job.data; + try { + const result = await handleRunRecording(fileName, runId); + return result; + } catch (error) { + logger.error('Error running workflow:', error); + throw error; + } }, { connection }); worker.on('completed', async (job: any) => { - logger.log(`info`, `Job ${job.id} completed for ${job.data.fileName}_${job.data.runId}`); + logger.log(`info`, `Job ${job.id} completed for ${job.data.fileName}_${job.data.runId}`); - await worker.close(); - await workflowQueue.close(); - logger.log(`info`, `Worker and queue have been closed.`); + await worker.close(); + await workflowQueue.close(); + logger.log(`info`, `Worker and queue have been closed.`); }); worker.on('failed', async (job: any, err) => { - logger.log(`error`, `Job ${job.id} failed for ${job.data.fileName}_${job.data.runId}:`, err); + logger.log(`error`, `Job ${job.id} failed for ${job.data.fileName}_${job.data.runId}:`, err); - await worker.close(); - await workflowQueue.close(); - logger.log(`info`, `Worker and queue have been closed after failure.`); + await worker.close(); + await workflowQueue.close(); + logger.log(`info`, `Worker and queue have been closed after failure.`); }); async function jobCounts() { - const jobCounts = await workflowQueue.getJobCounts(); - console.log('Jobs:', jobCounts); + const jobCounts = await workflowQueue.getJobCounts(); + console.log('Jobs:', jobCounts); } jobCounts(); From 215c6120a11f3ea372cf8a32f53616752d5f5f25 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Mon, 7 Oct 2024 01:22:12 +0530 Subject: [PATCH 08/20] chore: remove unused imports --- server/src/worker.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/server/src/worker.ts b/server/src/worker.ts index a45e525f..5bf388f2 100644 --- a/server/src/worker.ts +++ b/server/src/worker.ts @@ -1,14 +1,6 @@ -import fs from "fs"; -import { uuid } from "uuidv4"; -import { chromium } from "playwright"; -import { io, Socket } from "socket.io-client"; import { Queue, Worker } from 'bullmq'; import IORedis from 'ioredis'; -import { readFile, saveFile } from "./workflow-management/storage"; -import { createRemoteBrowserForRun, destroyRemoteBrowser } from './browser-management/controller'; import logger from './logger'; -import { browserPool } from "./server"; -import { googleSheetUpdateTasks, processGoogleSheetUpdates } from "./workflow-management/integrations/gsheet"; import { handleRunRecording } from "./workflow-management/scheduler"; const connection = new IORedis({ From 39d62fb3f82dd41bb7c29cf53ac2d5b770802ddf Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Mon, 7 Oct 2024 01:22:42 +0530 Subject: [PATCH 09/20] feat; export handleRUn reocridng --- server/src/workflow-management/scheduler/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/workflow-management/scheduler/index.ts b/server/src/workflow-management/scheduler/index.ts index 07d338c1..c988fcd0 100644 --- a/server/src/workflow-management/scheduler/index.ts +++ b/server/src/workflow-management/scheduler/index.ts @@ -205,7 +205,7 @@ function resetRecordingState(browserId: string, fileName: string, runId: string) logger.log(`info`, `reset values for ${browserId}, ${fileName}, and ${runId}`); } -async function handleRunRecording(fileName: string, runId: string) { +export async function handleRunRecording(fileName: string, runId: string) { try { const result = await runWorkflow(fileName, runId); const { browserId, runId: newRunId } = result; From 4f4ab9539a035ae6e70955a7597588e86b369fe6 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Mon, 7 Oct 2024 01:23:25 +0530 Subject: [PATCH 10/20] refactor: remove bullmq worker --- .../workflow-management/scheduler/index.ts | 50 ------------------- 1 file changed, 50 deletions(-) diff --git a/server/src/workflow-management/scheduler/index.ts b/server/src/workflow-management/scheduler/index.ts index c988fcd0..4a6fcc09 100644 --- a/server/src/workflow-management/scheduler/index.ts +++ b/server/src/workflow-management/scheduler/index.ts @@ -10,56 +10,6 @@ import logger from '../../logger'; import { browserPool } from "../../server"; import { googleSheetUpdateTasks, processGoogleSheetUpdates } from "../integrations/gsheet"; -const connection = new IORedis({ - host: 'localhost', - port: 6379, - maxRetriesPerRequest: null, -}); - -connection.on('connect', () => { - console.log('Connected to Redis!'); -}); - -connection.on('error', (err) => { - console.error('Redis connection error:', err); -}); - -const workflowQueue = new Queue('workflow', { connection }); - -export const worker = new Worker('workflow', async job => { - const { fileName, runId } = job.data; - try { - const result = await handleRunRecording(fileName, runId); - return result; - } catch (error) { - logger.error('Error running workflow:', error); - throw error; - } -}, { connection }); - -worker.on('completed', async (job: any) => { - logger.log(`info`, `Job ${job.id} completed for ${job.data.fileName}_${job.data.runId}`); - - await worker.close(); - await workflowQueue.close(); - logger.log(`info`, `Worker and queue have been closed.`); -}); - -worker.on('failed', async (job: any, err) => { - logger.log(`error`, `Job ${job.id} failed for ${job.data.fileName}_${job.data.runId}:`, err); - - await worker.close(); - await workflowQueue.close(); - logger.log(`info`, `Worker and queue have been closed after failure.`); -}); - -async function jobCounts() { - const jobCounts = await workflowQueue.getJobCounts(); - console.log('Jobs:', jobCounts); -} - -jobCounts(); - async function runWorkflow(fileName: string, runId: string) { if (!runId) { runId = uuid(); From 5091948b1215b9214ad03604bfb04b57a4382fc6 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Mon, 7 Oct 2024 01:23:49 +0530 Subject: [PATCH 11/20] fix: workflowQueue export --- server/src/workflow-management/scheduler/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/workflow-management/scheduler/index.ts b/server/src/workflow-management/scheduler/index.ts index 4a6fcc09..94e11cf0 100644 --- a/server/src/workflow-management/scheduler/index.ts +++ b/server/src/workflow-management/scheduler/index.ts @@ -187,4 +187,4 @@ function cleanupSocketListeners(socket: Socket, browserId: string, runId: string logger.log('info', `Cleaned up listeners for browserId: ${browserId}, runId: ${runId}`); } -export { workflowQueue, runWorkflow }; \ No newline at end of file +export { runWorkflow }; \ No newline at end of file From fb7b093fd3f70711467ed53b6f4baa4ec10b14fc Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Mon, 7 Oct 2024 01:24:17 +0530 Subject: [PATCH 12/20] chore: remove unused imports --- server/src/workflow-management/scheduler/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/server/src/workflow-management/scheduler/index.ts b/server/src/workflow-management/scheduler/index.ts index 94e11cf0..1fcef079 100644 --- a/server/src/workflow-management/scheduler/index.ts +++ b/server/src/workflow-management/scheduler/index.ts @@ -2,8 +2,6 @@ import fs from "fs"; import { uuid } from "uuidv4"; import { chromium } from "playwright"; import { io, Socket } from "socket.io-client"; -import { Queue, Worker } from 'bullmq'; -import IORedis from 'ioredis'; import { readFile, saveFile } from "../storage"; import { createRemoteBrowserForRun, destroyRemoteBrowser } from '../../browser-management/controller'; import logger from '../../logger'; From 5b502dcca343148a9a7373e9e105398aac325aa8 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Mon, 7 Oct 2024 01:25:58 +0530 Subject: [PATCH 13/20] fix: broken workflowQueue improt --- server/src/routes/storage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/routes/storage.ts b/server/src/routes/storage.ts index 1b43de7b..a5a019df 100644 --- a/server/src/routes/storage.ts +++ b/server/src/routes/storage.ts @@ -10,12 +10,12 @@ import { chromium } from "playwright"; import { browserPool } from "../server"; import fs from "fs"; import { uuid } from "uuidv4"; -import { workflowQueue } from '../workflow-management/scheduler'; import moment from 'moment-timezone'; import cron from 'node-cron'; import { googleSheetUpdateTasks, processGoogleSheetUpdates } from '../workflow-management/integrations/gsheet'; import { getDecryptedProxyConfig } from './proxy'; import { requireSignIn } from '../middlewares/auth'; +import { workflowQueue } from '../worker'; export const router = Router(); From 78f4b0a18f71d89287c9e6bafb8b35b172cd0fae Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Mon, 7 Oct 2024 01:26:16 +0530 Subject: [PATCH 14/20] chore: -rm desc --- server/src/routes/storage.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/server/src/routes/storage.ts b/server/src/routes/storage.ts index a5a019df..c7ad154e 100644 --- a/server/src/routes/storage.ts +++ b/server/src/routes/storage.ts @@ -1,7 +1,3 @@ -/** - * RESTful API endpoints handling the recording storage. -*/ - import { Router } from 'express'; import logger from "../logger"; import { deleteFile, readFile, readFiles, saveFile } from "../workflow-management/storage"; From 7b21ce4cdcaa0326586c75dd2643f023ab3ff2f3 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Mon, 7 Oct 2024 01:28:22 +0530 Subject: [PATCH 15/20] feat: !close the worker on completed and failed --- server/src/worker.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/server/src/worker.ts b/server/src/worker.ts index 5bf388f2..8a2e5e97 100644 --- a/server/src/worker.ts +++ b/server/src/worker.ts @@ -32,18 +32,10 @@ const worker = new Worker('workflow', async job => { worker.on('completed', async (job: any) => { logger.log(`info`, `Job ${job.id} completed for ${job.data.fileName}_${job.data.runId}`); - - await worker.close(); - await workflowQueue.close(); - logger.log(`info`, `Worker and queue have been closed.`); }); worker.on('failed', async (job: any, err) => { logger.log(`error`, `Job ${job.id} failed for ${job.data.fileName}_${job.data.runId}:`, err); - - await worker.close(); - await workflowQueue.close(); - logger.log(`info`, `Worker and queue have been closed after failure.`); }); async function jobCounts() { From c714d6df5d8f81553c8dab345ffe9e7a6711927a Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Mon, 7 Oct 2024 01:28:48 +0530 Subject: [PATCH 16/20] chore: console log worker run status --- server/src/worker.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/src/worker.ts b/server/src/worker.ts index 8a2e5e97..c75104d1 100644 --- a/server/src/worker.ts +++ b/server/src/worker.ts @@ -38,6 +38,8 @@ worker.on('failed', async (job: any, err) => { logger.log(`error`, `Job ${job.id} failed for ${job.data.fileName}_${job.data.runId}:`, err); }); +console.log('Worker is running...'); + async function jobCounts() { const jobCounts = await workflowQueue.getJobCounts(); console.log('Jobs:', jobCounts); From ee453b9069601af9c04e99bb620bee0c55d2f0f2 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Mon, 7 Oct 2024 01:37:50 +0530 Subject: [PATCH 17/20] feat: fork worker --- server/src/server.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/server/src/server.ts b/server/src/server.ts index cfd67d09..9f65ca14 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -14,6 +14,7 @@ import csrf from 'csurf'; import { SERVER_PORT } from "./constants/config"; import { Server } from "socket.io"; import { readdirSync } from "fs" +import { fork } from 'child_process'; const csrfProtection = csrf({ cookie: true }) @@ -60,6 +61,17 @@ readdirSync(path.join(__dirname, 'api')).forEach((r) => { } }); +const workerProcess = fork(path.resolve(__dirname, './worker.ts')); +workerProcess.on('message', (message) => { + console.log('Message from worker:', message); +}); +workerProcess.on('error', (error) => { + console.error(`Worker error: ${error}`); +}); +workerProcess.on('exit', (code) => { + console.log(`Worker exited with code: ${code}`); +}); + app.get('/', function (req, res) { return res.send('Maxun server started 🚀'); }); From 5383576557c37b74c44938897168367c3426460a Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Mon, 7 Oct 2024 01:38:35 +0530 Subject: [PATCH 18/20] feat: clearer messages --- server/src/server.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/server.ts b/server/src/server.ts index 9f65ca14..1eaa2df4 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -63,10 +63,10 @@ readdirSync(path.join(__dirname, 'api')).forEach((r) => { const workerProcess = fork(path.resolve(__dirname, './worker.ts')); workerProcess.on('message', (message) => { - console.log('Message from worker:', message); + console.log(`Message from worker: ${message}`); }); workerProcess.on('error', (error) => { - console.error(`Worker error: ${error}`); + console.error(`Error in worker: ${error}`); }); workerProcess.on('exit', (code) => { console.log(`Worker exited with code: ${code}`); From bba92f103066d126d34af62604b65abc048c7207 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Mon, 7 Oct 2024 01:40:13 +0530 Subject: [PATCH 19/20] feat: graceful shutdown of server --- server/src/server.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server/src/server.ts b/server/src/server.ts index 1eaa2df4..645c2e9c 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -85,3 +85,9 @@ server.listen(SERVER_PORT, async () => { await syncDB(); logger.log('info', `Server listening on port ${SERVER_PORT}`); }); + +process.on('SIGINT', () => { + console.log('Main app shutting down...'); + workerProcess.kill(); + process.exit(); +}); From 34b53510d7943b288bc96fefddb1026f9c50eb9a Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Mon, 7 Oct 2024 01:42:13 +0530 Subject: [PATCH 20/20] chore: lint --- server/src/worker.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/src/worker.ts b/server/src/worker.ts index c75104d1..3afb39c5 100644 --- a/server/src/worker.ts +++ b/server/src/worker.ts @@ -47,4 +47,9 @@ async function jobCounts() { jobCounts(); +process.on('SIGINT', () => { + console.log('Worker shutting down...'); + process.exit(); +}); + export { workflowQueue, worker }; \ No newline at end of file