100 lines
2.7 KiB
JavaScript
100 lines
2.7 KiB
JavaScript
const { Queue, Worker } = require("bullmq");
|
|
const { sendTaskEmail } = require("../../email/sendemail");
|
|
|
|
let emailQueue;
|
|
let worker;
|
|
|
|
const loadEmailQueue = async ({ pubClient, logger, redisHelpers }) => {
|
|
if (!emailQueue) {
|
|
logger.logger.info("Initializing Notifications Email Queue");
|
|
emailQueue = new Queue("notificationsEmails", {
|
|
connection: pubClient,
|
|
prefix: "{BULLMQ}",
|
|
defaultJobOptions: {
|
|
attempts: 3,
|
|
backoff: {
|
|
type: "exponential",
|
|
delay: 1000
|
|
}
|
|
}
|
|
});
|
|
|
|
// Initialize the worker during queue setup
|
|
worker = new Worker(
|
|
"notificationsEmails",
|
|
async (job) => {
|
|
const { subject, body, recipients } = job.data;
|
|
logger.logger.debug(`Processing email job ${job.id} for ${recipients.length} recipients`);
|
|
|
|
await sendTaskEmail({
|
|
to: recipients.map((r) => r.user),
|
|
subject,
|
|
type: "text",
|
|
text: body
|
|
});
|
|
|
|
logger.logger.debug(`Email job ${job.id} processed successfully`);
|
|
},
|
|
{
|
|
connection: pubClient,
|
|
prefix: "{BULLMQ}",
|
|
concurrency: 2, // Reduced for multi-node setup; adjust based on load
|
|
limiter: {
|
|
max: 10, // Max 10 jobs per minute per worker
|
|
duration: 60 * 1000 // 1 minute
|
|
}
|
|
}
|
|
);
|
|
|
|
// Worker event handlers
|
|
worker.on("completed", (job) => {
|
|
logger.logger.debug(`Job ${job.id} completed`);
|
|
});
|
|
|
|
worker.on("failed", (job, err) => {
|
|
logger.logger.error(`Job ${job.id} failed: ${err.message}`, { error: err });
|
|
});
|
|
|
|
worker.on("error", (err) => {
|
|
logger.logger.error("Worker error:", { error: err });
|
|
});
|
|
|
|
// Graceful shutdown handling
|
|
const shutdown = async () => {
|
|
if (worker) {
|
|
logger.logger.info("Closing email queue worker...");
|
|
await worker.close();
|
|
logger.logger.info("Email queue worker closed");
|
|
}
|
|
};
|
|
|
|
process.on("SIGTERM", shutdown);
|
|
process.on("SIGINT", shutdown);
|
|
}
|
|
|
|
return emailQueue;
|
|
};
|
|
|
|
const getQueue = () => {
|
|
if (!emailQueue) {
|
|
throw new Error("Email queue not initialized. Ensure loadEmailQueue is called during bootstrap.");
|
|
}
|
|
return emailQueue;
|
|
};
|
|
|
|
const dispatchEmailsToQueue = async ({ emailsToDispatch, logger }) => {
|
|
const emailQueue = getQueue();
|
|
|
|
for (const email of emailsToDispatch) {
|
|
const { subject, body, recipients } = email;
|
|
await emailQueue.add("send-email", {
|
|
subject,
|
|
body,
|
|
recipients
|
|
}); // Job options moved to defaultJobOptions in Queue
|
|
logger.logger.debug(`Added email to queue: ${subject} for ${recipients.length} recipients`);
|
|
}
|
|
};
|
|
|
|
module.exports = { loadEmailQueue, getQueue, dispatchEmailsToQueue };
|