Added option to spawn multiple sender processes
This commit is contained in:
parent
88fe24a709
commit
8ca1fbb535
12 changed files with 262 additions and 135 deletions
|
@ -1,28 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
let cache = module.exports.cache = new Map();
|
||||
|
||||
module.exports.push = (name, value) => {
|
||||
if (!cache.has(name)) {
|
||||
cache.set(name, []);
|
||||
} else if (!Array.isArray(cache.get(name))) {
|
||||
cache.set(name, [].concat(cache.get(name) || []));
|
||||
}
|
||||
cache.get(name).push(value);
|
||||
};
|
||||
|
||||
module.exports.shift = name => {
|
||||
if (!cache.has(name)) {
|
||||
return false;
|
||||
}
|
||||
if (!Array.isArray(cache.get(name))) {
|
||||
let value = cache.get(name);
|
||||
cache.delete(name);
|
||||
return value;
|
||||
}
|
||||
let value = cache.get(name).shift();
|
||||
if (!cache.get(name).length) {
|
||||
cache.delete(name);
|
||||
}
|
||||
return value;
|
||||
};
|
94
lib/db.js
94
lib/db.js
|
@ -2,5 +2,99 @@
|
|||
|
||||
let config = require('config');
|
||||
let mysql = require('mysql');
|
||||
let redis = require('redis');
|
||||
let Lock = require('redfour');
|
||||
|
||||
module.exports = mysql.createPool(config.mysql);
|
||||
if (config.redis.enabled) {
|
||||
|
||||
module.exports.redis = redis.createClient(config.redis);
|
||||
|
||||
let queueLock = new Lock({
|
||||
redis: config.redis,
|
||||
namespace: 'mailtrain:lock'
|
||||
});
|
||||
|
||||
module.exports.getLock = (id, callback) => {
|
||||
queueLock.waitAcquireLock(id, 60 * 1000 /* Lock expires after 60sec */ , 10 * 1000 /* Wait for lock for up to 10sec */ , (err, lock) => {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
if (!lock) {
|
||||
return callback(null, false);
|
||||
}
|
||||
return callback(null, {
|
||||
lock,
|
||||
release(done) {
|
||||
queueLock.releaseLock(lock, done);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.clearCache = (key, callback) => {
|
||||
module.exports.redis.del(key, err => callback(err));
|
||||
};
|
||||
|
||||
module.exports.addToCache = (key, value, callback) => {
|
||||
if (!value) {
|
||||
return setImmediate(() => callback());
|
||||
}
|
||||
module.exports.redis.multi().
|
||||
lpush('mailtrain:cache:' + key, JSON.stringify(value)).
|
||||
expire('mailtrain:cache:' + key, 24 * 3600).
|
||||
exec(err => callback(err));
|
||||
};
|
||||
|
||||
module.exports.getFromCache = (key, callback) => {
|
||||
module.exports.redis.rpop('mailtrain:cache:' + key, (err, value) => {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
try {
|
||||
value = JSON.parse(value);
|
||||
} catch (E) {
|
||||
return callback(E);
|
||||
}
|
||||
|
||||
return callback(null, value);
|
||||
});
|
||||
};
|
||||
|
||||
} else {
|
||||
// fakelock. does not lock anything
|
||||
module.exports.getLock = (id, callback) => {
|
||||
setImmediate(() => callback(null, {
|
||||
lock: false,
|
||||
release(done) {
|
||||
setImmediate(done);
|
||||
}
|
||||
}));
|
||||
};
|
||||
|
||||
let caches = new Map();
|
||||
|
||||
module.exports.clearCache = (key, callback) => {
|
||||
caches.delete(key);
|
||||
setImmediate(() => callback());
|
||||
};
|
||||
|
||||
module.exports.addToCache = (key, value, callback) => {
|
||||
if (!caches.has(key)) {
|
||||
caches.set(key, []);
|
||||
}
|
||||
caches.get(key).push(value);
|
||||
setImmediate(() => callback());
|
||||
};
|
||||
|
||||
module.exports.getFromCache = (key, callback) => {
|
||||
let value;
|
||||
if (caches.has(key)) {
|
||||
value = caches.get(key).shift();
|
||||
if (!caches.get(key).length) {
|
||||
caches.delete(key);
|
||||
}
|
||||
}
|
||||
setImmediate(() => callback(null, value));
|
||||
};
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ let nodemailer = require('nodemailer');
|
|||
let openpgpEncrypt = require('nodemailer-openpgp').openpgpEncrypt;
|
||||
let settings = require('./models/settings');
|
||||
let tools = require('./tools');
|
||||
let caches = require('./caches');
|
||||
let db = require('./db');
|
||||
let Handlebars = require('handlebars');
|
||||
let fs = require('fs');
|
||||
let path = require('path');
|
||||
|
@ -156,6 +156,7 @@ function createMailer(callback) {
|
|||
rejectUnauthorized: !configItems.smtpSelfSigned
|
||||
}
|
||||
}, config.nodemailer);
|
||||
|
||||
module.exports.transport.use('stream', openpgpEncrypt({
|
||||
signingKey: configItems.pgpPrivateKey,
|
||||
passphrase: configItems.pgpPassphrase
|
||||
|
@ -187,8 +188,9 @@ function createMailer(callback) {
|
|||
}
|
||||
};
|
||||
|
||||
caches.cache.delete('sender queue');
|
||||
return callback(null, module.exports.transport);
|
||||
db.clearCache('sender', () => {
|
||||
callback(null, module.exports.transport);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ let isUrl = require('is-url');
|
|||
let feed = require('../feed');
|
||||
let log = require('npmlog');
|
||||
let mailer = require('../mailer');
|
||||
let caches = require('../caches');
|
||||
let humanize = require('humanize');
|
||||
|
||||
let allowedKeys = ['description', 'from', 'address', 'reply_to', 'subject', 'template', 'source_url', 'list', 'segment', 'html', 'text', 'tracking_disabled'];
|
||||
|
@ -894,8 +893,9 @@ module.exports.delete = (id, callback) => {
|
|||
return callback(err);
|
||||
}
|
||||
|
||||
caches.cache.delete('sender queue');
|
||||
return callback(null, affected);
|
||||
db.clearCache('sender', () => {
|
||||
callback(null, affected);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -959,8 +959,9 @@ module.exports.pause = (id, callback) => {
|
|||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
caches.cache.delete('sender queue');
|
||||
return callback(null, true);
|
||||
db.clearCache('sender', () => {
|
||||
callback(null, true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -987,23 +988,24 @@ module.exports.reset = (id, callback) => {
|
|||
return callback(err);
|
||||
}
|
||||
|
||||
caches.cache.delete('sender queue');
|
||||
connection.query('UPDATE links SET `clicks`=0 WHERE campaign=?', [id], err => {
|
||||
if (err) {
|
||||
connection.release();
|
||||
return callback(err);
|
||||
}
|
||||
connection.query('TRUNCATE TABLE `campaign__' + id + '`', [id], err => {
|
||||
db.clearCache('sender', () => {
|
||||
connection.query('UPDATE links SET `clicks`=0 WHERE campaign=?', [id], err => {
|
||||
if (err) {
|
||||
connection.release();
|
||||
return callback(err);
|
||||
}
|
||||
connection.query('TRUNCATE TABLE `campaign_tracker__' + id + '`', [id], err => {
|
||||
connection.release();
|
||||
connection.query('TRUNCATE TABLE `campaign__' + id + '`', [id], err => {
|
||||
if (err) {
|
||||
connection.release();
|
||||
return callback(err);
|
||||
}
|
||||
return callback(null, true);
|
||||
connection.query('TRUNCATE TABLE `campaign_tracker__' + id + '`', [id], err => {
|
||||
connection.release();
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
return callback(null, true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue