perf: make digests a little bit faster

and use batch.processArray
dont load data for users who have no email or have not confirmed their emails
v1.18.x
Barış Soner Uşaklı 4 years ago
parent b6493f896f
commit 0185ea1b4f

@ -216,22 +216,22 @@ Emailer.send = async (template, uid, params) => {
throw Error('[emailer] App not ready!'); throw Error('[emailer] App not ready!');
} }
const [userData, userSettings] = await Promise.all([ const userData = await User.getUserFields(uid, ['email', 'username', 'email:confirmed']);
User.getUserFields(uid, ['email', 'username', 'email:confirmed']),
User.getSettings(uid),
]);
if (!userData || !userData.email) { if (!userData || !userData.email) {
if (process.env.NODE_ENV === 'development') {
winston.warn(`uid : ${uid} has no email, not sending "${template}" email.`); winston.warn(`uid : ${uid} has no email, not sending "${template}" email.`);
}
return; return;
} }
const allowedTpls = ['verify_email', 'welcome', 'registration_accepted']; const allowedTpls = ['verify_email', 'welcome', 'registration_accepted'];
if (meta.config.requireEmailConfirmation && !userData['email:confirmed'] && !allowedTpls.includes(template)) { if (meta.config.requireEmailConfirmation && !userData['email:confirmed'] && !allowedTpls.includes(template)) {
if (process.env.NODE_ENV === 'development') {
winston.warn(`uid : ${uid} (${userData.email}) has not confirmed email, not sending "${template}" email.`); winston.warn(`uid : ${uid} (${userData.email}) has not confirmed email, not sending "${template}" email.`);
}
return; return;
} }
const userSettings = await User.getSettings(uid);
// Combined passed-in payload with default values // Combined passed-in payload with default values
params = { ...Emailer._defaultPayload, ...params }; params = { ...Emailer._defaultPayload, ...params };
params.uid = uid; params.uid = uid;

@ -1,6 +1,5 @@
'use strict'; 'use strict';
const async = require('async');
const winston = require('winston'); const winston = require('winston');
const nconf = require('nconf'); const nconf = require('nconf');
@ -29,7 +28,7 @@ Digest.execute = async function (payload) {
return; return;
} }
try { try {
winston.info(`[user/jobs] Digest (${payload.interval}) scheduling completed. Sending emails; this may take some time...`); winston.info(`[user/jobs] Digest (${payload.interval}) scheduling completed (${subscribers.length} subscribers). Sending emails; this may take some time...`);
await Digest.send({ await Digest.send({
interval: payload.interval, interval: payload.interval,
subscribers: subscribers, subscribers: subscribers,
@ -100,8 +99,13 @@ Digest.send = async function (data) {
return emailsSent; return emailsSent;
} }
await async.eachLimit(data.subscribers, 100, async (uid) => { await batch.processArray(data.subscribers, async (uids) => {
const userObj = await user.getUserFields(uid, ['uid', 'username', 'userslug', 'lastonline']); let userData = await user.getUsersFields(uids, ['uid', 'email', 'email:confirmed', 'username', 'userslug', 'lastonline']);
userData = userData.filter(u => u && u.email && (!meta.config.requireEmailConfirmation || userData['email:confirmed']));
if (!userData.length) {
return;
}
await Promise.all(userData.map(async (userObj) => {
const [notifications, topTopics, popularTopics, recentTopics] = await Promise.all([ const [notifications, topTopics, popularTopics, recentTopics] = await Promise.all([
user.notifications.getUnreadInterval(userObj.uid, data.interval), user.notifications.getUnreadInterval(userObj.uid, data.interval),
getTermTopics(data.interval, userObj.uid, 0, 9, 'votes'), getTermTopics(data.interval, userObj.uid, 0, 9, 'votes'),
@ -140,6 +144,10 @@ Digest.send = async function (data) {
if (data.interval !== 'alltime') { if (data.interval !== 'alltime') {
await db.sortedSetAdd('digest:delivery', now.getTime(), userObj.uid); await db.sortedSetAdd('digest:delivery', now.getTime(), userObj.uid);
} }
}));
}, {
interval: 1000,
batch: 100,
}); });
winston.info(`[user/jobs] Digest (${data.interval}) sending completed. ${emailsSent} emails sent.`); winston.info(`[user/jobs] Digest (${data.interval}) sending completed. ${emailsSent} emails sent.`);
}; };

Loading…
Cancel
Save