Files
bodyshop/server/notifications/queues/emailQueue.js

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 };