Upgrade codebase with safe es6 features

This commit is contained in:
Denis Bardadym
2019-01-17 14:16:53 +03:00
parent 36cecde895
commit 5c560b2682
43 changed files with 2553 additions and 2724 deletions
+29
View File
@@ -0,0 +1,29 @@
env:
node: true
parserOptions:
ecmaVersion: 6
extends:
- eslint:recommended
- plugin:node/recommended
rules:
valid-jsdoc: 0
func-style: 0
no-use-before-define: 0
camelcase: 1
no-unused-vars: 2
no-alert: 2
no-console: [2, { allow: ['warn', 'error'] }]
no-underscore-dangle: 0
strict: [2, 'global']
no-var: 2
prefer-arrow-callback: 2
prefer-const: 2
no-inner-declarations: 0
object-shorthand: [2, 'consistent-as-needed']
newline-per-chained-call: 2
node/no-deprecated-api: 0
+1
View File
@@ -1,2 +1,3 @@
node_modules
tmp
test
+9 -7
View File
@@ -1,13 +1,15 @@
var _ = require('lodash');
'use strict';
var builtinStrategies = {
fixed: function(delay) {
const _ = require('lodash');
const builtinStrategies = {
fixed(delay) {
return function() {
return delay;
};
},
exponential: function(delay) {
exponential(delay) {
return function(attemptsMade) {
return Math.round((Math.pow(2, attemptsMade) - 1) * delay);
};
@@ -29,7 +31,7 @@ function lookupStrategy(backoff, customStrategies) {
}
module.exports = {
normalize: function(backoff) {
normalize(backoff) {
if (_.isFinite(backoff)) {
return {
type: 'fixed',
@@ -40,9 +42,9 @@ module.exports = {
}
},
calculate: function(backoff, attemptsMade, customStrategies, err) {
calculate(backoff, attemptsMade, customStrategies, err) {
if (backoff) {
var strategy = lookupStrategy(backoff, customStrategies);
const strategy = lookupStrategy(backoff, customStrategies);
return strategy(attemptsMade, err);
}
+17 -17
View File
@@ -12,27 +12,27 @@
*/
'use strict';
var fs = require('fs');
var path = require('path');
var promisify = require('util.promisify'); //TODO in node >= 8 could be removed
const fs = require('fs');
const path = require('path');
const promisify = require('util.promisify'); //TODO in node >= 8 could be removed
var utils = require('../utils');
const utils = require('../utils');
//TODO node >= 10 could be used require('fs').promises()
var _fs = {
const _fs = {
readdirAsync: promisify(fs.readdir),
readFileAsync: promisify(fs.readFile)
};
module.exports = (function() {
var scripts;
let scripts;
return function(client) {
return utils.isRedisReady(client).then(function() {
return utils.isRedisReady(client).then(() => {
scripts = scripts || loadScripts(__dirname);
return scripts.then(function(_scripts) {
return _scripts.forEach(function(command) {
return scripts.then(_scripts => {
return _scripts.forEach(command => {
return client.defineCommand(command.name, command.options);
});
});
@@ -43,19 +43,19 @@ module.exports = (function() {
function loadScripts(dir) {
return _fs
.readdirAsync(dir)
.then(function(files) {
return files.filter(function(file) {
.then(files => {
return files.filter(file => {
return path.extname(file) === '.lua';
});
})
.then(function(files) {
.then(files => {
return Promise.all(
files.map(function(file) {
var longName = path.basename(file, '.lua');
var name = longName.split('-')[0];
var numberOfKeys = parseInt(longName.split('-')[1]);
files.map(file => {
const longName = path.basename(file, '.lua');
const name = longName.split('-')[0];
const numberOfKeys = parseInt(longName.split('-')[1]);
return _fs.readFileAsync(path.join(dir, file)).then(function(lua) {
return _fs.readFileAsync(path.join(dir, file)).then(lua => {
return {
name: name,
options: { numberOfKeys: numberOfKeys, lua: lua.toString() }
+21 -27
View File
@@ -1,8 +1,7 @@
/*eslint-env node */
'use strict';
var _ = require('lodash');
var Job = require('./job');
const _ = require('lodash');
const Job = require('./job');
module.exports = function(Queue) {
Queue.prototype.getJob = function(jobId) {
@@ -10,12 +9,10 @@ module.exports = function(Queue) {
};
Queue.prototype._commandByType = function(types, count, callback) {
var _this = this;
return _.map(types, function(type) {
return _.map(types, type => {
type = type === 'waiting' ? 'wait' : type; // alias
var key = _this.toKey(type);
const key = this.toKey(type);
switch (type) {
case 'completed':
@@ -44,7 +41,7 @@ module.exports = function(Queue) {
// Queue#getJobCountByTypes('completed', 'failed') => completed + failed count
// Queue#getJobCountByTypes('completed,waiting', 'failed') => completed + waiting + failed count
Queue.prototype.getJobCountByTypes = function() {
return this.getJobCounts.apply(this, arguments).then(function(result) {
return this.getJobCounts.apply(this, arguments).then(result => {
return _.chain(result)
.values()
.sum()
@@ -57,16 +54,16 @@ module.exports = function(Queue) {
*
*/
Queue.prototype.getJobCounts = function() {
var types = parseTypeArg(arguments);
var multi = this.multi();
const types = parseTypeArg(arguments);
const multi = this.multi();
this._commandByType(types, true, function(key, command) {
this._commandByType(types, true, (key, command) => {
multi[command](key);
});
return multi.exec().then(function(res) {
var counts = {};
res.forEach(function(res, index) {
return multi.exec().then(res => {
const counts = {};
res.forEach((res, index) => {
counts[types[index]] = res[1] || 0;
});
return counts;
@@ -119,15 +116,13 @@ module.exports = function(Queue) {
};
Queue.prototype.getRanges = function(types, start, end, asc) {
var _this = this;
start = _.isUndefined(start) ? 0 : start;
end = _.isUndefined(end) ? -1 : end;
var multi = this.multi();
var multiCommands = [];
const multi = this.multi();
const multiCommands = [];
_this._commandByType(parseTypeArg(types), false, function(key, command) {
this._commandByType(parseTypeArg(types), false, (key, command) => {
switch (command) {
case 'lrange':
if (asc) {
@@ -148,11 +143,11 @@ module.exports = function(Queue) {
}
});
return multi.exec().then(function(responses) {
var results = [];
return multi.exec().then(responses => {
let results = [];
responses.forEach(function(response, index) {
var result = response[1] || [];
responses.forEach((response, index) => {
const result = response[1] || [];
if (asc && multiCommands[index] === 'lrange') {
results = results.concat(result.reverse());
@@ -165,15 +160,14 @@ module.exports = function(Queue) {
};
Queue.prototype.getJobs = function(types, start, end, asc) {
var _this = this;
return this.getRanges(types, start, end, asc).then(function(jobIds) {
return Promise.all(jobIds.map(_this.getJobFromId));
return this.getRanges(types, start, end, asc).then(jobIds => {
return Promise.all(jobIds.map(this.getJobFromId));
});
};
};
function parseTypeArg(args) {
var types = _.chain([])
const types = _.chain([])
.concat(args)
.join(',')
.split(/\s*,\s*/g)
+105 -117
View File
@@ -1,14 +1,13 @@
/*eslint-env node */
'use strict';
var _ = require('lodash');
var utils = require('./utils');
var scripts = require('./scripts');
var debuglog = require('debuglog')('bull');
var errors = require('./errors');
var backoffs = require('./backoffs');
const _ = require('lodash');
const utils = require('./utils');
const scripts = require('./scripts');
const debuglog = require('debuglog')('bull');
const errors = require('./errors');
const backoffs = require('./backoffs');
var FINISHED_WATCHDOG = 5000;
const FINISHED_WATCHDOG = 5000;
/**
interface JobOptions
@@ -20,7 +19,7 @@ interface JobOptions
*/
// queue: Queue, data: {}, opts: JobOptions
var Job = function(queue, name, data, opts) {
const Job = function(queue, name, data, opts) {
if (typeof name !== 'string') {
opts = data;
data = name;
@@ -44,7 +43,7 @@ var Job = function(queue, name, data, opts) {
};
function setDefaultOpts(opts) {
var _opts = Object.assign({}, opts);
const _opts = Object.assign({}, opts);
_opts.attempts = typeof _opts.attempts == 'undefined' ? 1 : _opts.attempts;
_opts.delay = typeof _opts.delay == 'undefined' ? 0 : Number(_opts.delay);
@@ -60,9 +59,9 @@ function setDefaultOpts(opts) {
Job.DEFAULT_JOB_NAME = '__default__';
function addJob(queue, job) {
var opts = job.opts;
const opts = job.opts;
var jobData = job.toData();
const jobData = job.toData();
return scripts.addJob(
queue.client,
queue,
@@ -77,14 +76,14 @@ function addJob(queue, job) {
}
Job.create = function(queue, name, data, opts) {
var job = new Job(queue, name, data, opts);
const job = new Job(queue, name, data, opts);
return queue
.isReady()
.then(function() {
.then(() => {
return addJob(queue, job);
})
.then(function(jobId) {
.then(jobId => {
job.id = jobId;
job.lockKey = job.toKey(jobId) + ':lock';
debuglog('Job added', jobId);
@@ -97,7 +96,7 @@ Job.fromId = function(queue, jobId) {
if (!jobId) {
return Promise.resolve();
}
return queue.client.hgetall(queue.toKey(jobId)).then(function(jobData) {
return queue.client.hgetall(queue.toKey(jobId)).then(jobData => {
return utils.isEmpty(jobData) ? null : Job.fromJSON(queue, jobData, jobId);
});
};
@@ -119,7 +118,7 @@ Job.prototype.update = function(data) {
};
Job.prototype.toJSON = function() {
var opts = Object.assign({}, this.opts);
const opts = Object.assign({}, this.opts);
return {
id: this.id,
name: this.name,
@@ -138,7 +137,7 @@ Job.prototype.toJSON = function() {
};
Job.prototype.toData = function() {
var json = this.toJSON();
const json = this.toJSON();
json.data = JSON.stringify(json.data);
json.opts = JSON.stringify(json.opts);
@@ -161,7 +160,7 @@ Job.prototype.lockKey = function() {
same time.
*/
Job.prototype.takeLock = function() {
return scripts.takeLock(this.queue, this).then(function(lock) {
return scripts.takeLock(this.queue, this).then(lock => {
return lock || false;
});
};
@@ -170,10 +169,9 @@ Job.prototype.takeLock = function() {
Releases the lock. Only locks owned by the queue instance can be released.
*/
Job.prototype.releaseLock = function() {
var _this = this;
return scripts.releaseLock(this.queue, this.id).then(function(unlocked) {
return scripts.releaseLock(this.queue, this.id).then(unlocked => {
if (unlocked != 1) {
throw new Error('Could not release lock for job ' + _this.id);
throw new Error('Could not release lock for job ' + this.id);
}
});
};
@@ -190,7 +188,7 @@ Job.prototype.moveToCompleted = function(returnValue, ignoreLock) {
returnValue = utils.tryCatch(JSON.stringify, JSON, [returnValue]);
if (returnValue === utils.errorObject) {
var err = utils.errorObject.value;
const err = utils.errorObject.value;
return Promise.reject(err);
}
@@ -213,21 +211,20 @@ Job.prototype.discard = function() {
* @returns void
*/
Job.prototype.moveToFailed = function(err, ignoreLock) {
var _this = this;
this.failedReason = err.message;
return new Promise(function(resolve, reject) {
var command;
var multi = _this.queue.client.multi();
_this._saveAttempt(multi, err);
return new Promise((resolve, reject) => {
let command;
const multi = this.queue.client.multi();
this._saveAttempt(multi, err);
// Check if an automatic retry should be performed
var moveToFailed = false;
if (_this.attemptsMade < _this.opts.attempts && !_this._discarded) {
let moveToFailed = false;
if (this.attemptsMade < this.opts.attempts && !this._discarded) {
// Check if backoff is needed
var delay = backoffs.calculate(
_this.opts.backoff,
_this.attemptsMade,
_this.queue.settings.backoffStrategies,
const delay = backoffs.calculate(
this.opts.backoff,
this.attemptsMade,
this.queue.settings.backoffStrategies,
err
);
@@ -236,9 +233,9 @@ Job.prototype.moveToFailed = function(err, ignoreLock) {
moveToFailed = true;
} else if (delay) {
// If so, move to delayed (need to unlock job in this case!)
var args = scripts.moveToDelayedArgs(
_this.queue,
_this.id,
const args = scripts.moveToDelayedArgs(
this.queue,
this.id,
Date.now() + delay,
ignoreLock
);
@@ -246,7 +243,7 @@ Job.prototype.moveToFailed = function(err, ignoreLock) {
command = 'delayed';
} else {
// If not, retry immediately
multi.retryJob(scripts.retryJobArgs(_this, ignoreLock));
multi.retryJob(scripts.retryJobArgs(this, ignoreLock));
command = 'retry';
}
} else {
@@ -255,19 +252,19 @@ Job.prototype.moveToFailed = function(err, ignoreLock) {
}
if (moveToFailed) {
var args = scripts.moveToFailedArgs(
_this,
const args = scripts.moveToFailedArgs(
this,
err.message,
_this.opts.removeOnFail,
this.opts.removeOnFail,
ignoreLock
);
multi.moveToFinished(args);
command = 'failed';
}
return multi.exec().then(function(results) {
var code = _.last(results)[1];
return multi.exec().then(results => {
const code = _.last(results)[1];
if (code < 0) {
return reject(scripts.finishedErrors(code, _this.id, command));
return reject(scripts.finishedErrors(code, this.id, command));
}
resolve();
}, reject);
@@ -279,10 +276,10 @@ Job.prototype.moveToDelayed = function(timestamp, ignoreLock) {
};
Job.prototype.promote = function() {
var queue = this.queue;
var jobId = this.id;
const queue = this.queue;
const jobId = this.id;
var script = [
const script = [
'if redis.call("ZREM", KEYS[1], ARGV[1]) == 1 then',
' redis.call("LPUSH", KEYS[2], ARGV[1])',
' return 0',
@@ -291,13 +288,13 @@ Job.prototype.promote = function() {
'end'
].join('\n');
var keys = _.map(['delayed', 'wait'], function(name) {
const keys = _.map(['delayed', 'wait'], name => {
return queue.toKey(name);
});
return queue.client
.eval(script, keys.length, keys[0], keys[1], jobId)
.then(function(result) {
.then(result => {
if (result === -1) {
throw new Error('Job ' + jobId + ' is not in a delayed state');
}
@@ -312,33 +309,30 @@ Job.prototype.promote = function() {
* rejects, it indicates that the script failed to execute
*/
Job.prototype.retry = function() {
var _this = this;
return this.queue.isReady().then(function() {
_this.failedReason = null;
_this.finishedOn = null;
_this.processedOn = null;
return this.queue.isReady().then(() => {
this.failedReason = null;
this.finishedOn = null;
this.processedOn = null;
return _this.queue.client
return this.queue.client
.hdel(
_this.queue.toKey(_this.id),
this.queue.toKey(this.id),
'finishedOn',
'processedOn',
'failedReason'
)
.then(function(/*redisResult*/) {
return scripts
.reprocessJob(_this, { state: 'failed' })
.then(function(result) {
if (result === 1) {
return;
} else if (result === 0) {
throw new Error(errors.Messages.RETRY_JOB_NOT_EXIST);
} else if (result === -1) {
throw new Error(errors.Messages.RETRY_JOB_IS_LOCKED);
} else if (result === -2) {
throw new Error(errors.Messages.RETRY_JOB_NOT_FAILED);
}
});
.then((/*redisResult*/) => {
return scripts.reprocessJob(this, { state: 'failed' }).then(result => {
if (result === 1) {
return;
} else if (result === 0) {
throw new Error(errors.Messages.RETRY_JOB_NOT_EXIST);
} else if (result === -1) {
throw new Error(errors.Messages.RETRY_JOB_IS_LOCKED);
} else if (result === -2) {
throw new Error(errors.Messages.RETRY_JOB_NOT_FAILED);
}
});
});
});
};
@@ -368,14 +362,13 @@ Job.prototype.isPaused = function() {
};
Job.prototype.isStuck = function() {
return this.getState().then(function(state) {
return this.getState().then(state => {
return state === 'stuck';
});
};
Job.prototype.getState = function() {
var _this = this;
var fns = [
const fns = [
{ fn: 'isCompleted', state: 'completed' },
{ fn: 'isFailed', state: 'failed' },
{ fn: 'isDelayed', state: 'delayed' },
@@ -385,27 +378,27 @@ Job.prototype.getState = function() {
];
return fns
.reduce(function(result, fn) {
return result.then(function(state) {
.reduce((result, fn) => {
return result.then(state => {
if (state) {
return state;
}
return _this[fn.fn]().then(function(result) {
return this[fn.fn]().then(result => {
return result ? fn.state : null;
});
});
}, Promise.resolve())
.then(function(result) {
.then(result => {
return result ? result : 'stuck';
});
};
Job.prototype.remove = function() {
var queue = this.queue;
var job = this;
const queue = this.queue;
const job = this;
return queue.isReady().then(function() {
return scripts.remove(queue, job.id).then(function(removed) {
return queue.isReady().then(() => {
return scripts.remove(queue, job.id).then(removed => {
if (removed) {
queue.emit('removed', job);
} else {
@@ -419,17 +412,15 @@ Job.prototype.remove = function() {
* Returns a promise the resolves when the job has finished. (completed or failed).
*/
Job.prototype.finished = function() {
var _this = this;
return Promise.all([
this.queue._registerEvent('global:completed'),
this.queue._registerEvent('global:failed')
]).then(function() {
return _this.queue.isReady().then(function() {
return scripts.isFinished(_this).then(function(status) {
var finished = status > 0;
]).then(() => {
return this.queue.isReady().then(() => {
return scripts.isFinished(this).then(status => {
const finished = status > 0;
if (finished) {
return Job.fromId(_this.queue, _this.id).then(function(job) {
return Job.fromId(this.queue, this.id).then(job => {
if (status == 2) {
throw new Error(job.failedReason);
} else {
@@ -437,11 +428,10 @@ Job.prototype.finished = function() {
}
});
} else {
return new Promise(function(resolve, reject) {
var interval;
function onCompleted(jobId, resultValue) {
if (String(jobId) === String(_this.id)) {
var result = void 0;
return new Promise((resolve, reject) => {
const onCompleted = (jobId, resultValue) => {
if (String(jobId) === String(this.id)) {
let result = void 0;
try {
if (typeof resultValue === 'string') {
result = JSON.parse(resultValue);
@@ -453,29 +443,29 @@ Job.prototype.finished = function() {
resolve(result);
removeListeners();
}
}
};
function onFailed(jobId, failedReason) {
if (String(jobId) === String(_this.id)) {
const onFailed = (jobId, failedReason) => {
if (String(jobId) === String(this.id)) {
reject(new Error(failedReason));
removeListeners();
}
}
};
_this.queue.on('global:completed', onCompleted);
_this.queue.on('global:failed', onFailed);
this.queue.on('global:completed', onCompleted);
this.queue.on('global:failed', onFailed);
function removeListeners() {
const removeListeners = () => {
clearInterval(interval);
_this.queue.removeListener('global:completed', onCompleted);
_this.queue.removeListener('global:failed', onFailed);
}
this.queue.removeListener('global:completed', onCompleted);
this.queue.removeListener('global:failed', onFailed);
};
//
// Watchdog
//
interval = setInterval(function() {
if (_this.queue.closing) {
const interval = setInterval(() => {
if (this.queue.closing) {
removeListeners();
// TODO(manast) maybe we would need a more graceful way to get out of this interval.
reject(
@@ -484,10 +474,10 @@ Job.prototype.finished = function() {
)
);
}
scripts.isFinished(_this).then(function(status) {
var finished = status > 0;
scripts.isFinished(this).then(status => {
const finished = status > 0;
if (finished) {
Job.fromId(_this.queue, _this.id).then(function(job) {
Job.fromId(this.queue, this.id).then(job => {
removeListeners();
if (status == 2) {
reject(new Error(job.failedReason));
@@ -511,7 +501,7 @@ Job.prototype.finished = function() {
Job.prototype._isDone = function(list) {
return this.queue.client
.zscore(this.queue.toKey(list), this.id)
.then(function(score) {
.then(score => {
return score !== null;
});
};
@@ -527,7 +517,7 @@ Job.prototype._isInList = function(list) {
Job.prototype._saveAttempt = function(multi, err) {
this.attemptsMade++;
var params = {
const params = {
attemptsMade: this.attemptsMade
};
@@ -543,10 +533,10 @@ Job.prototype._saveAttempt = function(multi, err) {
};
Job.fromJSON = function(queue, json, jobId) {
var data = JSON.parse(json.data || '{}');
var opts = JSON.parse(json.opts || '{}');
const data = JSON.parse(json.data || '{}');
const opts = JSON.parse(json.opts || '{}');
var job = new Job(queue, json.name || Job.DEFAULT_JOB_NAME, data, opts);
const job = new Job(queue, json.name || Job.DEFAULT_JOB_NAME, data, opts);
job.id = json.id || jobId;
job._progress = JSON.parse(json.progress || 0);
@@ -573,9 +563,7 @@ Job.fromJSON = function(queue, json, jobId) {
};
function getTraces(stacktrace) {
var _traces;
_traces = utils.tryCatch(JSON.parse, JSON, [stacktrace]);
const _traces = utils.tryCatch(JSON.parse, JSON, [stacktrace]);
if (_traces === utils.errorObject || !(_traces instanceof Array)) {
return [];
@@ -585,7 +573,7 @@ function getTraces(stacktrace) {
}
function getReturnValue(_value) {
var value = utils.tryCatch(JSON.parse, JSON, [_value]);
const value = utils.tryCatch(JSON.parse, JSON, [_value]);
if (value !== utils.errorObject) {
return value;
} else {
+19 -20
View File
@@ -1,10 +1,10 @@
'use strict';
var fork = require('child_process').fork;
var path = require('path');
var _ = require('lodash');
const fork = require('child_process').fork;
const path = require('path');
const _ = require('lodash');
var ChildPool = function ChildPool() {
const ChildPool = function ChildPool() {
if (!(this instanceof ChildPool)) {
return new ChildPool();
}
@@ -14,30 +14,29 @@ var ChildPool = function ChildPool() {
};
ChildPool.prototype.retain = function(processFile) {
var _this = this;
var child = _this.getFree(processFile).pop();
let child = this.getFree(processFile).pop();
if (child) {
_this.retained[child.pid] = child;
this.retained[child.pid] = child;
return Promise.resolve(child);
}
// if node process is running with --inspect, don't include that option
// when spawning the children
var execArgv = _.filter(process.execArgv, function(arg) {
const execArgv = _.filter(process.execArgv, arg => {
return arg.indexOf('--inspect') === -1;
});
child = fork(path.join(__dirname, './master.js'), {
execArgv: execArgv
execArgv
});
child.processFile = processFile;
_this.retained[child.pid] = child;
this.retained[child.pid] = child;
child.on('exit', _this.remove.bind(_this, child));
child.on('exit', this.remove.bind(this, child));
return initChild(child, processFile).then(function() {
return initChild(child, processFile).then(() => {
return child;
});
};
@@ -50,9 +49,9 @@ ChildPool.prototype.release = function(child) {
ChildPool.prototype.remove = function(child) {
delete this.retained[child.pid];
var free = this.getFree(child.processFile);
const free = this.getFree(child.processFile);
var childIndex = free.indexOf(child);
const childIndex = free.indexOf(child);
if (childIndex > -1) {
free.splice(childIndex, 1);
}
@@ -64,11 +63,11 @@ ChildPool.prototype.kill = function(child, signal) {
};
ChildPool.prototype.clean = function() {
var children = _.values(this.retained).concat(this.getAllFree());
var _this = this;
children.forEach(function(child) {
const children = _.values(this.retained).concat(this.getAllFree());
children.forEach(child => {
// TODO: We may want to use SIGKILL if the process does not die after some time.
_this.kill(child, 'SIGTERM');
this.kill(child, 'SIGTERM');
});
this.retained = {};
@@ -83,8 +82,8 @@ ChildPool.prototype.getAllFree = function() {
return _.flatten(_.values(this.free));
};
var initChild = function(child, processFile) {
return new Promise(function(resolve) {
const initChild = function(child, processFile) {
return new Promise(resolve => {
child.send({ cmd: 'init', value: processFile }, resolve);
});
};
+12 -10
View File
@@ -3,19 +3,21 @@
* processor and the main process.
*
*/
var status;
var processor;
'use strict';
let status;
let processor;
//TODO remove for node >= 10
require('promise.prototype.finally').shim();
var promisify = require('util.promisify');
const promisify = require('util.promisify');
// https://stackoverflow.com/questions/18391212/is-it-not-possible-to-stringify-an-error-using-json-stringify
if (!('toJSON' in Error.prototype)) {
Object.defineProperty(Error.prototype, 'toJSON', {
value: function() {
var alt = {};
const alt = {};
Object.getOwnPropertyNames(this).forEach(function(key) {
alt[key] = this[key];
@@ -28,7 +30,7 @@ if (!('toJSON' in Error.prototype)) {
});
}
process.on('message', function(msg) {
process.on('message', msg => {
switch (msg.cmd) {
case 'init':
processor = require(msg.value);
@@ -39,7 +41,7 @@ process.on('message', function(msg) {
if (processor.length > 1) {
processor = promisify(processor);
} else {
var origProcessor = processor;
const origProcessor = processor;
processor = function() {
try {
return Promise.resolve(origProcessor.apply(null, arguments));
@@ -61,13 +63,13 @@ process.on('message', function(msg) {
status = 'STARTED';
Promise.resolve(processor(wrapJob(msg.job)) || {})
.then(
function(result) {
result => {
process.send({
cmd: 'completed',
value: result
});
},
function(err) {
err => {
if (!err.message) {
err = new Error(err);
}
@@ -77,7 +79,7 @@ process.on('message', function(msg) {
});
}
)
.finally(function() {
.finally(() => {
status = 'IDLE';
});
break;
@@ -86,7 +88,7 @@ process.on('message', function(msg) {
}
});
process.on('uncaughtException', function(err) {
process.on('uncaughtException', err => {
if (!err.message) {
err = new Error(err);
}
+7 -6
View File
@@ -5,13 +5,13 @@ require('promise.prototype.finally').shim();
module.exports = function(processFile, childPool) {
return function process(job) {
return childPool.retain(processFile).then(function(child) {
return childPool.retain(processFile).then(child => {
child.send({
cmd: 'start',
job: job
});
var done = new Promise(function(resolve, reject) {
const done = new Promise((resolve, reject) => {
function handler(msg) {
switch (msg.cmd) {
case 'completed':
@@ -19,12 +19,13 @@ module.exports = function(processFile, childPool) {
resolve(msg.value);
break;
case 'failed':
case 'error':
case 'error': {
child.removeListener('message', handler);
var err = new Error();
const err = new Error();
Object.assign(err, msg.value);
reject(err);
break;
}
case 'progress':
job.progress(msg.value);
break;
@@ -32,12 +33,12 @@ module.exports = function(processFile, childPool) {
}
child.on('message', handler);
child.on('exit', function(exitCode) {
child.on('exit', exitCode => {
reject(new Error('Unexpected exit code: ' + exitCode));
});
});
return done.finally(function() {
return done.finally(() => {
childPool.release(child);
});
});
+275 -311
View File
File diff suppressed because it is too large Load Diff
+53 -57
View File
@@ -1,11 +1,10 @@
/*eslint-env node */
'use strict';
var _ = require('lodash');
var parser = require('cron-parser');
var crypto = require('crypto');
const _ = require('lodash');
const parser = require('cron-parser');
const crypto = require('crypto');
var Job = require('./job');
const Job = require('./job');
module.exports = function(Queue) {
Queue.prototype.nextRepeatableJob = function(
@@ -14,63 +13,46 @@ module.exports = function(Queue) {
opts,
skipCheckExists
) {
var _this = this;
var client = this.client;
var repeat = opts.repeat;
var prevMillis = opts.prevMillis || 0;
const client = this.client;
const repeat = opts.repeat;
const prevMillis = opts.prevMillis || 0;
if (!prevMillis && opts.jobId) {
repeat.jobId = opts.jobId;
}
var currentCount = repeat.count ? repeat.count + 1 : 1;
const currentCount = repeat.count ? repeat.count + 1 : 1;
if (!_.isUndefined(repeat.limit) && currentCount > repeat.limit) {
return Promise.resolve();
}
var now = Date.now();
let now = Date.now();
now = prevMillis < now ? now : prevMillis;
var nextMillis = getNextMillis(now, repeat);
const nextMillis = getNextMillis(now, repeat);
if (nextMillis) {
var jobId = repeat.jobId ? repeat.jobId + ':' : ':';
var repeatJobKey = getRepeatKey(name, repeat, jobId);
const jobId = repeat.jobId ? repeat.jobId + ':' : ':';
const repeatJobKey = getRepeatKey(name, repeat, jobId);
if (skipCheckExists) {
return createNextJob();
}
// Check that the repeatable job hasn't been removed
// TODO: a lua script would be better here
return client
.zscore(_this.keys.repeat, repeatJobKey)
.then(function handleZScore(repeatableExists) {
// The job could have been deleted since this check
if (repeatableExists) {
return createNextJob();
}
return Promise.resolve();
});
function createNextJob() {
const createNextJob = () => {
return client
.zadd(_this.keys.repeat, nextMillis, repeatJobKey)
.then(function() {
.zadd(this.keys.repeat, nextMillis, repeatJobKey)
.then(() => {
//
// Generate unique job id for this iteration.
//
var customId = getRepeatJobId(
const customId = getRepeatJobId(
name,
jobId,
nextMillis,
md5(repeatJobKey)
);
now = Date.now();
var delay = nextMillis - now;
const delay = nextMillis - now;
return Job.create(
_this,
this,
name,
data,
_.defaultsDeep(
@@ -87,28 +69,42 @@ module.exports = function(Queue) {
)
);
});
};
if (skipCheckExists) {
return createNextJob();
}
// Check that the repeatable job hasn't been removed
// TODO: a lua script would be better here
return client
.zscore(this.keys.repeat, repeatJobKey)
.then(repeatableExists => {
// The job could have been deleted since this check
if (repeatableExists) {
return createNextJob();
}
return Promise.resolve();
});
} else {
return Promise.resolve();
}
};
Queue.prototype.removeRepeatable = function(name, repeat) {
var _this = this;
if (typeof name !== 'string') {
repeat = name;
name = Job.DEFAULT_JOB_NAME;
}
return this.isReady().then(function() {
var jobId = repeat.jobId ? repeat.jobId + ':' : ':';
var repeatJobKey = getRepeatKey(name, repeat, jobId);
var repeatJobId = getRepeatJobId(name, jobId, '', md5(repeatJobKey));
var queueKey = _this.keys[''];
return _this.client.removeRepeatable(
_this.keys.repeat,
_this.keys.delayed,
return this.isReady().then(() => {
const jobId = repeat.jobId ? repeat.jobId + ':' : ':';
const repeatJobKey = getRepeatKey(name, repeat, jobId);
const repeatJobId = getRepeatJobId(name, jobId, '', md5(repeatJobKey));
const queueKey = this.keys[''];
return this.client.removeRepeatable(
this.keys.repeat,
this.keys.delayed,
repeatJobId,
repeatJobKey,
queueKey
@@ -117,16 +113,16 @@ module.exports = function(Queue) {
};
Queue.prototype.getRepeatableJobs = function(start, end, asc) {
var key = this.keys.repeat;
const key = this.keys.repeat;
start = start || 0;
end = end || -1;
return (asc
? this.client.zrange(key, start, end, 'WITHSCORES')
: this.client.zrevrange(key, start, end, 'WITHSCORES')
).then(function(result) {
var jobs = [];
for (var i = 0; i < result.length; i += 2) {
var data = result[i].split(':');
).then(result => {
const jobs = [];
for (let i = 0; i < result.length; i += 2) {
const data = result[i].split(':');
jobs.push({
key: result[i],
name: data[0],
@@ -150,11 +146,11 @@ module.exports = function(Queue) {
}
function getRepeatKey(name, repeat, jobId) {
var endDate = repeat.endDate
const endDate = repeat.endDate
? new Date(repeat.endDate).getTime() + ':'
: ':';
var tz = repeat.tz ? repeat.tz + ':' : ':';
var suffix = repeat.cron ? tz + repeat.cron : String(repeat.every);
const tz = repeat.tz ? repeat.tz + ':' : ':';
const suffix = repeat.cron ? tz + repeat.cron : String(repeat.every);
return name + ':' + jobId + endDate + suffix;
}
@@ -170,15 +166,15 @@ module.exports = function(Queue) {
return Math.floor(millis / opts.every) * opts.every + opts.every;
}
var currentDate =
const currentDate =
opts.startDate && new Date(opts.startDate) > new Date(millis)
? new Date(opts.startDate)
: new Date(millis);
var interval = parser.parseExpression(
const interval = parser.parseExpression(
opts.cron,
_.defaults(
{
currentDate: currentDate
currentDate
},
opts
)
+76 -84
View File
@@ -2,34 +2,33 @@
* Includes all the scripts needed by the queue and jobs.
*/
/*eslint-env node */
'use strict';
var _ = require('lodash');
var debuglog = require('debuglog')('bull');
const _ = require('lodash');
const debuglog = require('debuglog')('bull');
// TO Deprecate.
function execScript(client, hash, lua, numberOfKeys) {
var args = _.drop(arguments, 4);
const args = _.drop(arguments, 4);
if (!client[hash]) {
debuglog(hash, lua, args);
client.defineCommand(hash, { numberOfKeys: numberOfKeys, lua: lua });
client.defineCommand(hash, { numberOfKeys, lua });
}
return client[hash](args);
}
var scripts = {
isJobInList: function(client, listKey, jobId) {
return client.isJobInList([listKey, jobId]).then(function(result) {
const scripts = {
isJobInList(client, listKey, jobId) {
return client.isJobInList([listKey, jobId]).then(result => {
return result === 1;
});
},
addJob: function(client, queue, job, opts) {
var queueKeys = queue.keys;
var keys = [
addJob(client, queue, job, opts) {
const queueKeys = queue.keys;
let keys = [
queueKeys.wait,
queueKeys.paused,
queueKeys['meta-paused'],
@@ -38,7 +37,7 @@ var scripts = {
queueKeys.priority
];
var args = [
const args = [
queueKeys[''],
_.isUndefined(opts.customJobId) ? '' : opts.customJobId,
job.name,
@@ -55,17 +54,17 @@ var scripts = {
return client.addJob(keys);
},
pause: function(queue, pause) {
var src = 'wait',
pause(queue, pause) {
let src = 'wait',
dst = 'paused';
if (!pause) {
src = 'paused';
dst = 'wait';
}
var keys = _.map(
const keys = _.map(
[src, dst, 'meta-paused', pause ? 'paused' : 'resumed'],
function(name) {
name => {
return queue.toKey(name);
}
);
@@ -73,9 +72,9 @@ var scripts = {
return queue.client.pause(keys.concat([pause ? 'paused' : 'resumed']));
},
moveToActive: function(queue, jobId) {
var queueKeys = queue.keys;
var keys = [queueKeys.wait, queueKeys.active, queueKeys.priority];
moveToActive(queue, jobId) {
const queueKeys = queue.keys;
const keys = [queueKeys.wait, queueKeys.active, queueKeys.priority];
keys[3] = keys[1] + '@' + queue.token;
keys[4] = queueKeys.stalled;
@@ -83,7 +82,7 @@ var scripts = {
keys[6] = queueKeys.delayed;
keys[7] = queueKeys.drained;
var args = [
const args = [
queueKeys[''],
queue.token,
queue.settings.lockDuration,
@@ -101,21 +100,21 @@ var scripts = {
return queue.client.moveToActive(keys.concat(args)).then(raw2jobData);
},
updateProgress: function(job, progress) {
var queue = job.queue;
var keys = [job.id, 'progress'].map(function(name) {
updateProgress(job, progress) {
const queue = job.queue;
const keys = [job.id, 'progress'].map(name => {
return queue.toKey(name);
});
var progressJson = JSON.stringify(progress);
const progressJson = JSON.stringify(progress);
return queue.client
.updateProgress(keys, [progressJson, job.id + ',' + progressJson])
.then(function() {
.then(() => {
queue.emit('progress', job, progress);
});
},
moveToFinishedArgs: function(
moveToFinishedArgs(
job,
val,
propVal,
@@ -124,10 +123,10 @@ var scripts = {
ignoreLock,
notFetch
) {
var queue = job.queue;
var queueKeys = queue.keys;
const queue = job.queue;
const queueKeys = queue.keys;
var keys = [
const keys = [
queueKeys.active,
queueKeys[target],
queue.toKey(job.id),
@@ -136,7 +135,7 @@ var scripts = {
queueKeys.active + '@' + queue.token
];
var args = [
const args = [
job.id,
Date.now(),
propVal,
@@ -153,15 +152,8 @@ var scripts = {
return keys.concat(args);
},
moveToFinished: function(
job,
val,
propVal,
shouldRemove,
target,
ignoreLock
) {
var args = scripts.moveToFinishedArgs(
moveToFinished(job, val, propVal, shouldRemove, target, ignoreLock) {
const args = scripts.moveToFinishedArgs(
job,
val,
propVal,
@@ -169,7 +161,7 @@ var scripts = {
target,
ignoreLock
);
return job.queue.client.moveToFinished(args).then(function(result) {
return job.queue.client.moveToFinished(args).then(result => {
if (result < 0) {
throw scripts.finishedErrors(result, job.id, 'finished');
} else if (result) {
@@ -179,7 +171,7 @@ var scripts = {
});
},
finishedErrors: function(code, jobId, command) {
finishedErrors(code, jobId, command) {
switch (code) {
case -1:
return new Error('Missing key for job ' + jobId + ' ' + command);
@@ -189,7 +181,7 @@ var scripts = {
},
// TODO: add a retention argument for completed and finished jobs (in time).
moveToCompleted: function(job, returnvalue, removeOnComplete, ignoreLock) {
moveToCompleted(job, returnvalue, removeOnComplete, ignoreLock) {
return scripts.moveToFinished(
job,
returnvalue,
@@ -200,7 +192,7 @@ var scripts = {
);
},
moveToFailedArgs: function(job, failedReason, removeOnFailed, ignoreLock) {
moveToFailedArgs(job, failedReason, removeOnFailed, ignoreLock) {
return scripts.moveToFinishedArgs(
job,
failedReason,
@@ -212,8 +204,8 @@ var scripts = {
);
},
moveToFailed: function(job, failedReason, removeOnFailed, ignoreLock) {
var args = scripts.moveToFailedArgs(
moveToFailed(job, failedReason, removeOnFailed, ignoreLock) {
const args = scripts.moveToFailedArgs(
job,
failedReason,
'failedReason',
@@ -225,15 +217,15 @@ var scripts = {
return scripts.moveToFinished(args);
},
isFinished: function(job) {
var keys = _.map(['completed', 'failed'], function(key) {
isFinished(job) {
const keys = _.map(['completed', 'failed'], key => {
return job.queue.toKey(key);
});
return job.queue.client.isFinished(keys.concat([job.id]));
},
moveToDelayedArgs: function(queue, jobId, timestamp, ignoreLock) {
moveToDelayedArgs(queue, jobId, timestamp, ignoreLock) {
//
// Bake in the job id first 12 bits into the timestamp
// to guarantee correct execution order of delayed jobs
@@ -249,7 +241,7 @@ var scripts = {
timestamp = timestamp * 0x1000 + (jobId & 0xfff);
}
var keys = _.map(['active', 'delayed', jobId], function(name) {
const keys = _.map(['active', 'delayed', jobId], name => {
return queue.toKey(name);
});
return keys.concat([
@@ -259,9 +251,9 @@ var scripts = {
]);
},
moveToDelayed: function(queue, jobId, timestamp, ignoreLock) {
var args = scripts.moveToDelayedArgs(queue, jobId, timestamp, ignoreLock);
return queue.client.moveToDelayed(args).then(function(result) {
moveToDelayed(queue, jobId, timestamp, ignoreLock) {
const args = scripts.moveToDelayedArgs(queue, jobId, timestamp, ignoreLock);
return queue.client.moveToDelayed(args).then(result => {
switch (result) {
case -1:
throw new Error(
@@ -279,8 +271,8 @@ var scripts = {
});
},
remove: function(queue, jobId) {
var keys = _.map(
remove(queue, jobId) {
const keys = _.map(
[
'active',
'wait',
@@ -291,7 +283,7 @@ var scripts = {
'priority',
jobId
],
function(name) {
name => {
return queue.toKey(name);
}
);
@@ -299,7 +291,7 @@ var scripts = {
return queue.client.removeJob(keys.concat([jobId, queue.token]));
},
extendLock: function(queue, jobId) {
extendLock(queue, jobId) {
return queue.client.extendLock([
queue.toKey(jobId) + ':lock',
queue.keys.stalled,
@@ -309,14 +301,14 @@ var scripts = {
]);
},
releaseLock: function(queue, jobId) {
releaseLock(queue, jobId) {
return queue.client.releaseLock([
queue.toKey(jobId) + ':lock',
queue.token
]);
},
takeLock: function(queue, job) {
takeLock(queue, job) {
return queue.client.takeLock([
job.lockKey,
queue.token,
@@ -328,8 +320,8 @@ var scripts = {
It checks if the job in the top of the delay set should be moved back to the
top of the wait queue (so that it will be processed as soon as possible)
*/
updateDelaySet: function(queue, delayedTimestamp) {
var keys = [
updateDelaySet(queue, delayedTimestamp) {
const keys = [
queue.keys.delayed,
queue.keys.active,
queue.keys.wait,
@@ -338,7 +330,7 @@ var scripts = {
queue.keys['meta-paused']
];
var args = [queue.toKey(''), delayedTimestamp, queue.token];
const args = [queue.toKey(''), delayedTimestamp, queue.token];
return queue.client.updateDelaySet(keys.concat(args));
},
@@ -350,8 +342,8 @@ var scripts = {
* back to wait to be re-processed. To prevent jobs from cycling endlessly between active and wait,
* (e.g. if the job handler keeps crashing), we limit the number stalled job recoveries to settings.maxStalledCount.
*/
moveUnlockedJobsToWait: function(queue) {
var keys = [
moveUnlockedJobsToWait(queue) {
const keys = [
queue.keys.stalled,
queue.keys.wait,
queue.keys.active,
@@ -360,7 +352,7 @@ var scripts = {
queue.keys['meta-paused'],
queue.keys.paused
];
var args = [
const args = [
queue.settings.maxStalledCount,
queue.toKey(''),
Date.now(),
@@ -370,11 +362,11 @@ var scripts = {
},
// TODO: Refactor into lua script
cleanJobsInSet: function(queue, set, ts, limit) {
var command;
var removeCommand;
var breakEarlyCommand = '';
var hash;
cleanJobsInSet(queue, set, ts, limit) {
let command;
let removeCommand;
let breakEarlyCommand = '';
let hash;
limit = limit || 0;
switch (set) {
@@ -404,7 +396,7 @@ var scripts = {
hash = hash + 'WithLimit';
}
var script = [
const script = [
command,
'local deleted = {}',
'local deletedCount = 0',
@@ -426,7 +418,7 @@ var scripts = {
'return deleted'
].join('\n');
var args = [
const args = [
queue.client,
hash,
script,
@@ -440,15 +432,15 @@ var scripts = {
return execScript.apply(scripts, args);
},
retryJobArgs: function(job, ignoreLock) {
var queue = job.queue;
var jobId = job.id;
retryJobArgs(job, ignoreLock) {
const queue = job.queue;
const jobId = job.id;
var keys = _.map(['active', 'wait', jobId], function(name) {
const keys = _.map(['active', 'wait', jobId], name => {
return queue.toKey(name);
});
var pushCmd = (job.opts.lifo ? 'R' : 'L') + 'PUSH';
const pushCmd = (job.opts.lifo ? 'R' : 'L') + 'PUSH';
return keys.concat([pushCmd, jobId, ignoreLock ? '0' : job.queue.token]);
},
@@ -467,17 +459,17 @@ var scripts = {
* -1 means the job is currently locked and can't be retried.
* -2 means the job was not found in the expected set
*/
reprocessJob: function(job, options) {
var queue = job.queue;
reprocessJob(job, options) {
const queue = job.queue;
var keys = [
const keys = [
queue.toKey(job.id),
queue.toKey(job.id) + ':lock',
queue.toKey(options.state),
queue.toKey('wait')
];
var args = [job.id, (job.opts.lifo ? 'R' : 'L') + 'PUSH', queue.token];
const args = [job.id, (job.opts.lifo ? 'R' : 'L') + 'PUSH', queue.token];
return queue.client.reprocessJob(keys.concat(args));
}
@@ -486,8 +478,8 @@ var scripts = {
module.exports = scripts;
function array2obj(arr) {
var obj = {};
for (var i = 0; i < arr.length; i += 2) {
const obj = {};
for (let i = 0; i < arr.length; i += 2) {
obj[arr[i]] = arr[i + 1];
}
return obj;
@@ -495,9 +487,9 @@ function array2obj(arr) {
function raw2jobData(raw) {
if (raw) {
var jobData = raw[0];
const jobData = raw[0];
if (jobData.length) {
var job = array2obj(jobData);
const job = array2obj(jobData);
return [job, raw[1]];
}
}
+14 -17
View File
@@ -1,8 +1,7 @@
/*eslint-env node */
'use strict';
var _ = require('lodash');
var uuid = require('uuid');
const _ = require('lodash');
const uuid = require('uuid');
/**
Timer Manager
@@ -72,9 +71,9 @@ function TimerManager() {
@returns {Number} id - The timer id. Used to clear the timer
*/
TimerManager.prototype.set = function(name, delay, fn) {
var id = uuid.v4();
var timer = setTimeout(
function(timerInstance, timeoutId) {
const id = uuid.v4();
const timer = setTimeout(
(timerInstance, timeoutId) => {
timerInstance.clear(timeoutId);
try {
fn();
@@ -91,8 +90,8 @@ TimerManager.prototype.set = function(name, delay, fn) {
// other fields are useful for
// troubleshooting/debugging
this.timers[id] = {
name: name,
timer: timer
name,
timer
};
this.idle = false;
@@ -106,8 +105,8 @@ TimerManager.prototype.set = function(name, delay, fn) {
remaining timers
*/
TimerManager.prototype.clear = function(id) {
var timers = this.timers;
var timer = timers[id];
const timers = this.timers;
const timer = timers[id];
if (!timer) {
return;
}
@@ -122,9 +121,8 @@ TimerManager.prototype.clear = function(id) {
};
TimerManager.prototype.clearAll = function() {
var _this = this;
_.each(this.timers, function(timer, id) {
_this.clear(id);
_.each(this.timers, (timer, id) => {
this.clear(id);
});
};
@@ -132,12 +130,11 @@ TimerManager.prototype.clearAll = function() {
* Returns a promise that resolves when there are no active timers.
*/
TimerManager.prototype.whenIdle = function() {
var _this = this;
return new Promise(function(resolve) {
if (_this.idle) {
return new Promise(resolve => {
if (this.idle) {
resolve();
} else {
_this.listeners.unshift(resolve);
this.listeners.unshift(resolve);
}
});
};
+3 -3
View File
@@ -1,5 +1,5 @@
'use strict';
var errorObject = { value: null };
const errorObject = { value: null };
function tryCatch(fn, ctx, args) {
try {
return fn.apply(ctx, args);
@@ -10,7 +10,7 @@ function tryCatch(fn, ctx, args) {
}
function isEmpty(obj) {
for (var key in obj) {
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
return false;
}
@@ -23,7 +23,7 @@ function isEmpty(obj) {
* @param {Redis} redis client
*/
function isRedisReady(client) {
return new Promise(function(resolve, reject) {
return new Promise((resolve, reject) => {
if (client.status === 'ready') {
resolve();
} else {
+19 -23
View File
@@ -1,7 +1,6 @@
/*eslint-env node */
'use strict';
var utils = require('./utils');
const utils = require('./utils');
module.exports = function(Queue) {
// IDEA, How to store metadata associated to a worker.
// create a key from the worker ID associated to the given name.
@@ -9,21 +8,19 @@ module.exports = function(Queue) {
// metadata of the worker. The worker key gets expired every 30 seconds or so, we renew the worker metadata.
//
Queue.prototype.setWorkerName = function() {
var _this = this;
return utils.isRedisReady(this.client).then(function() {
return _this.client.client('setname', _this.clientName());
return utils.isRedisReady(this.client).then(() => {
return this.client.client('setname', this.clientName());
});
};
Queue.prototype.getWorkers = function() {
var _this = this;
return utils
.isRedisReady(this.client)
.then(function() {
return _this.client.client('list');
.then(() => {
return this.client.client('list');
})
.then(function(clients) {
return _this.parseClientList(clients);
.then(clients => {
return this.parseClientList(clients);
});
};
@@ -36,22 +33,21 @@ module.exports = function(Queue) {
};
Queue.prototype.parseClientList = function(list) {
var _this = this;
var lines = list.split('\n');
var clients = [];
const lines = list.split('\n');
const clients = [];
lines.forEach(function(line) {
var client = {};
var keyValues = line.split(' ');
keyValues.forEach(function(keyValue) {
var index = keyValue.indexOf('=');
var key = keyValue.substring(0, index);
var value = keyValue.substring(index + 1);
lines.forEach(line => {
const client = {};
const keyValues = line.split(' ');
keyValues.forEach(keyValue => {
const index = keyValue.indexOf('=');
const key = keyValue.substring(0, index);
const value = keyValue.substring(index + 1);
client[key] = value;
});
var name = client['name'];
if (name && name.startsWith(_this.clientName())) {
client['name'] = _this.name;
const name = client['name'];
if (name && name.startsWith(this.clientName())) {
client['name'] = this.name;
clients.push(client);
}
});
+342 -438
View File
File diff suppressed because it is too large Load Diff
+9 -25
View File
@@ -28,19 +28,20 @@
"uuid": "^3.2.1"
},
"devDependencies": {
"chai": "^4.0.2",
"chai": "^4.2.0",
"coveralls": "^3.0.0",
"delay": "^4.1.0",
"eslint": "^4.19.1",
"eslint": "^5.12.0",
"eslint-plugin-node": "^8.0.1",
"expect.js": "^0.3.1",
"husky": "^1.1.4",
"husky": "^1.3.1",
"istanbul": "^0.4.5",
"lint-staged": "^8.0.4",
"lint-staged": "^8.1.0",
"mocha": "^5.1.1",
"mocha-lcov-reporter": "^1.3.0",
"moment": "^2.22.1",
"moment": "^2.23.0",
"p-reflect": "^1.0.0",
"prettier": "^1.15.2",
"prettier": "^1.15.3",
"sinon": "^5.0.7"
},
"scripts": {
@@ -62,24 +63,7 @@
"prettier": {
"singleQuote": true
},
"eslintConfig": {
"rules": {
"valid-jsdoc": 0,
"func-style": 0,
"no-use-before-define": 0,
"camelcase": 1,
"no-unused-vars": 1,
"no-alert": 1,
"no-console": [
2,
{
"allow": [
"warn",
"error"
]
}
],
"no-underscore-dangle": 0
}
"engines": {
"node": ">= 6"
}
}
-5
View File
@@ -1,5 +0,0 @@
{
"env": {
"mocha": true
}
}
+8
View File
@@ -0,0 +1,8 @@
extends:
- ../.eslintrc.yml
env:
mocha: true
rules:
no-process-exit: 0
+8 -9
View File
@@ -1,18 +1,17 @@
/*eslint-env node */
'use strict';
var Queue = require('../');
const Queue = require('../');
var STD_QUEUE_NAME = 'cluster test queue';
const STD_QUEUE_NAME = 'cluster test queue';
function buildQueue(name) {
var qName = name || STD_QUEUE_NAME;
const qName = name || STD_QUEUE_NAME;
return new Queue(qName, 6379, '127.0.0.1');
}
var queue = buildQueue();
const queue = buildQueue();
queue.process(1, function(job, jobDone) {
queue.process(1, (job, jobDone) => {
jobDone();
process.send({
id: job.jobId,
@@ -20,13 +19,13 @@ queue.process(1, function(job, jobDone) {
});
});
process.on('disconnect', function() {
process.on('disconnect', () => {
queue
.close()
.then(function() {
.then(() => {
// process.exit(0);
})
.catch(function(err) {
.catch(err => {
console.error(err);
// process.exit(-1);
});
+3 -2
View File
@@ -2,11 +2,12 @@
* A processor file to be used in tests.
*
*/
'use strict';
var delay = require('delay');
const delay = require('delay');
module.exports = function(/*job*/) {
return delay(500).then(function() {
return delay(500).then(() => {
return 42;
});
};
+3 -2
View File
@@ -2,11 +2,12 @@
* A processor file to be used in tests.
*
*/
'use strict';
var delay = require('delay');
const delay = require('delay');
module.exports = function(/*job*/) {
return delay(500).then(function() {
return delay(500).then(() => {
return 'bar';
});
};
+3 -2
View File
@@ -2,11 +2,12 @@
* A processor file to be used in tests.
*
*/
'use strict';
var delay = require('delay');
const delay = require('delay');
module.exports = function(job, done) {
delay(500).then(function() {
delay(500).then(() => {
done(null, 42);
});
};
+3 -2
View File
@@ -2,11 +2,12 @@
* A processor file to be used in tests.
*
*/
'use strict';
var delay = require('delay');
const delay = require('delay');
module.exports = function(job, done) {
delay(500).then(function() {
delay(500).then(() => {
done(new Error('Manually failed processor'));
});
};
+3 -2
View File
@@ -2,14 +2,15 @@
* A processor file to be used in tests.
*
*/
'use strict';
module.exports = function(job) {
setTimeout(function() {
setTimeout(() => {
if (typeof job.data.exitCode !== 'number') {
throw new Error('boom!');
}
process.exit(job.data.exitCode);
}, 100);
return new Promise(function() {});
return new Promise(() => {});
};
+4 -3
View File
@@ -2,12 +2,13 @@
* A processor file to be used in tests.
*
*/
'use strict';
var delay = require('delay');
const delay = require('delay');
module.exports = function(/*job*/) {
return delay(500).then(function() {
delay(100).then(function() {
return delay(500).then(() => {
delay(100).then(() => {
process.exit(0);
});
});
+3 -2
View File
@@ -2,11 +2,12 @@
* A processor file to be used in tests.
*
*/
'use strict';
var delay = require('delay');
const delay = require('delay');
module.exports = function(/*job*/) {
return delay(500).then(function() {
return delay(500).then(() => {
throw new Error('Manually failed processor');
});
};
+3 -2
View File
@@ -2,11 +2,12 @@
* A processor file to be used in tests.
*
*/
'use strict';
var delay = require('delay');
const delay = require('delay');
module.exports = function(/*job*/) {
return delay(500).then(function() {
return delay(500).then(() => {
return 'foo';
});
};
+7 -6
View File
@@ -2,27 +2,28 @@
* A processor file to be used in tests.
*
*/
'use strict';
var delay = require('delay');
const delay = require('delay');
module.exports = function(job) {
return delay(50)
.then(function() {
.then(() => {
job.progress(10);
return delay(100);
})
.then(function() {
.then(() => {
job.progress(27);
return delay(150);
})
.then(function() {
.then(() => {
job.progress(78);
return delay(100);
})
.then(function() {
.then(() => {
return job.progress(100);
})
.then(function() {
.then(() => {
return 37;
});
};
+3 -2
View File
@@ -2,11 +2,12 @@
* A processor file to be used in tests.
*
*/
'use strict';
var delay = require('delay');
const delay = require('delay');
module.exports = function(/*job*/) {
return delay(1000).then(function() {
return delay(1000).then(() => {
return 42;
});
};
+37 -38
View File
@@ -1,26 +1,25 @@
/*eslint-env node */
'use strict';
var expect = require('chai').expect;
var childPool = require('../lib/process/child-pool');
const expect = require('chai').expect;
const childPool = require('../lib/process/child-pool');
describe('Child pool', function() {
var pool;
describe('Child pool', () => {
let pool;
beforeEach(function() {
beforeEach(() => {
pool = new childPool();
});
afterEach(function() {
afterEach(() => {
pool.clean();
});
it('should return same child if free', function() {
var processor = __dirname + '/fixtures/fixture_processor_bar.js';
var child;
it('should return same child if free', () => {
const processor = __dirname + '/fixtures/fixture_processor_bar.js';
let child;
return pool
.retain(processor)
.then(function(_child) {
.then(_child => {
expect(_child).to.be.ok;
child = _child;
pool.release(child);
@@ -29,17 +28,17 @@ describe('Child pool', function() {
return pool.retain(processor);
})
.then(function(newChild) {
.then(newChild => {
expect(child).to.be.eql(newChild);
});
});
it('should return a new child if reused the last free one', function() {
var processor = __dirname + '/fixtures/fixture_processor_bar.js';
var child;
it('should return a new child if reused the last free one', () => {
const processor = __dirname + '/fixtures/fixture_processor_bar.js';
let child;
return pool
.retain(processor)
.then(function(_child) {
.then(_child => {
expect(_child).to.be.ok;
child = _child;
pool.release(child);
@@ -48,22 +47,22 @@ describe('Child pool', function() {
return pool.retain(processor);
})
.then(function(newChild) {
.then(newChild => {
expect(child).to.be.eql(newChild);
child = newChild;
return pool.retain(processor);
})
.then(function(newChild) {
.then(newChild => {
expect(child).not.to.be.eql(newChild);
});
});
it('should return a new child if none free', function() {
var processor = __dirname + '/fixtures/fixture_processor_bar.js';
var child;
it('should return a new child if none free', () => {
const processor = __dirname + '/fixtures/fixture_processor_bar.js';
let child;
return pool
.retain(processor)
.then(function(_child) {
.then(_child => {
expect(_child).to.be.ok;
child = _child;
@@ -71,17 +70,17 @@ describe('Child pool', function() {
return pool.retain(processor);
})
.then(function(newChild) {
.then(newChild => {
expect(child).to.not.be.eql(newChild);
});
});
it('should return a new child if killed', function() {
var processor = __dirname + '/fixtures/fixture_processor_bar.js';
var child;
it('should return a new child if killed', () => {
const processor = __dirname + '/fixtures/fixture_processor_bar.js';
let child;
return pool
.retain(processor)
.then(function(_child) {
.then(_child => {
expect(_child).to.be.ok;
child = _child;
@@ -91,14 +90,14 @@ describe('Child pool', function() {
return pool.retain(processor);
})
.then(function(newChild) {
.then(newChild => {
expect(child).to.not.be.eql(newChild);
});
});
it('should return a new child if many retained and none free', function() {
var processor = __dirname + '/fixtures/fixture_processor_bar.js';
var children;
it('should return a new child if many retained and none free', () => {
const processor = __dirname + '/fixtures/fixture_processor_bar.js';
let children;
return Promise.all([
pool.retain(processor),
@@ -108,19 +107,19 @@ describe('Child pool', function() {
pool.retain(processor),
pool.retain(processor)
])
.then(function(_children) {
.then(_children => {
children = _children;
expect(children).to.have.length(6);
return pool.retain(processor);
})
.then(function(child) {
.then(child => {
expect(children).not.to.include(child);
});
});
it('should return an old child if many retained and one free', function() {
var processor = __dirname + '/fixtures/fixture_processor_bar.js';
var children;
it('should return an old child if many retained and one free', () => {
const processor = __dirname + '/fixtures/fixture_processor_bar.js';
let children;
return Promise.all([
pool.retain(processor),
@@ -130,7 +129,7 @@ describe('Child pool', function() {
pool.retain(processor),
pool.retain(processor)
])
.then(function(_children) {
.then(_children => {
children = _children;
expect(children).to.have.length(6);
@@ -138,7 +137,7 @@ describe('Child pool', function() {
return pool.retain(processor);
})
.then(function(child) {
.then(child => {
expect(children).to.include(child);
});
});
+32 -33
View File
@@ -1,33 +1,32 @@
/*eslint-env node */
'use strict';
var cluster = require('cluster');
var os = require('os');
var path = require('path');
var Queue = require('../');
var expect = require('expect.js');
var redis = require('ioredis');
const cluster = require('cluster');
const os = require('os');
const path = require('path');
const Queue = require('../');
const expect = require('expect.js');
const redis = require('ioredis');
var STD_QUEUE_NAME = 'cluster test queue';
const STD_QUEUE_NAME = 'cluster test queue';
function buildQueue(name) {
var qName = name || STD_QUEUE_NAME;
const qName = name || STD_QUEUE_NAME;
return new Queue(qName, 6379, '127.0.0.1');
}
function purgeQueue(queue) {
// Since workers spawned only listen to the default queue,
// we need to purge all keys after each test
var client = new redis(6379, '127.0.0.1', {});
const client = new redis(6379, '127.0.0.1', {});
client.select(0);
var script = [
const script = [
'local KS = redis.call("KEYS", ARGV[1])',
'local result = redis.call("DEL", unpack(KS))',
'return'
].join('\n');
return queue.client.eval(script, 0, queue.toKey('*')).finally(function() {
return queue.client.eval(script, 0, queue.toKey('*')).finally(() => {
return client.quit();
});
}
@@ -36,19 +35,19 @@ cluster.setupMaster({
exec: path.join(__dirname, '/cluster_worker.js')
});
var workerMessageHandler;
let workerMessageHandler;
function workerMessageHandlerWrapper(message) {
if (workerMessageHandler) {
workerMessageHandler(message);
}
}
describe.skip('Cluster', function() {
var workers = [];
describe.skip('Cluster', () => {
const workers = [];
before(function() {
var worker;
var _i = 0;
before(() => {
let worker;
let _i = 0;
for (_i; _i < os.cpus().length - 1; _i++) {
worker = cluster.fork();
worker.on('message', workerMessageHandlerWrapper);
@@ -57,14 +56,14 @@ describe.skip('Cluster', function() {
}
});
var queue;
let queue;
afterEach(function() {
afterEach(() => {
if (queue) {
return purgeQueue(queue).then(function() {
return purgeQueue(queue).then(() => {
return queue.close
.bind(queue)()
.then(function() {
.then(() => {
queue = undefined;
workerMessageHandler = undefined;
});
@@ -72,20 +71,20 @@ describe.skip('Cluster', function() {
}
});
it('should process each job once', function(done) {
var jobs = [];
it('should process each job once', done => {
const jobs = [];
queue = buildQueue();
var numJobs = 100;
const numJobs = 100;
queue.on('stalled', function(job) {
queue.on('stalled', job => {
jobs.splice(jobs.indexOf(job.jobId), 1);
});
workerMessageHandler = function(job) {
jobs.push(job.id);
if (jobs.length === numJobs) {
var counts = {};
var j = 0;
const counts = {};
let j = 0;
for (j; j < jobs.length; j++) {
expect(counts[jobs[j]]).to.be(undefined);
counts[jobs[j]] = 1;
@@ -94,7 +93,7 @@ describe.skip('Cluster', function() {
}
};
var i = 0;
let i = 0;
for (i; i < numJobs; i++) {
queue.add({});
}
@@ -103,7 +102,7 @@ describe.skip('Cluster', function() {
it('should process delayed jobs in correct order', function(done) {
this.timeout(5000);
queue = buildQueue();
var order = 0;
let order = 0;
workerMessageHandler = function(job) {
expect(order).to.be.below(job.data.order);
@@ -139,7 +138,7 @@ describe.skip('Cluster', function() {
this.timeout(5000);
queue = buildQueue();
var order = 0;
let order = 0;
workerMessageHandler = function(job) {
expect(order).to.be.below(job.data.order);
@@ -161,8 +160,8 @@ describe.skip('Cluster', function() {
queue.add({ order: 10 }, { delay: 200 });
});
after(function() {
var _i = 0;
after(() => {
let _i = 0;
for (_i; _i < workers.length; _i++) {
workers[_i].kill();
}
+32 -33
View File
@@ -1,44 +1,43 @@
/*eslint-env node */
'use strict';
var expect = require('expect.js');
var utils = require('./utils');
var redis = require('ioredis');
const expect = require('expect.js');
const utils = require('./utils');
const redis = require('ioredis');
describe('connection', function() {
var queue;
var client;
describe('connection', () => {
let queue;
let client;
beforeEach(function() {
beforeEach(() => {
client = new redis();
return client.flushdb().then(function() {
return client.flushdb().then(() => {
queue = utils.buildQueue();
return queue;
});
});
afterEach(function() {
afterEach(() => {
return client.quit();
});
it('should recover from a connection loss', function(done) {
queue.on('error', function() {
it('should recover from a connection loss', done => {
queue.on('error', () => {
// error event has to be observed or the exception will bubble up
});
queue
.process(function(job, jobDone) {
.process((job, jobDone) => {
expect(job.data.foo).to.be.equal('bar');
jobDone();
queue.close();
})
.then(function() {
.then(() => {
done();
})
.catch(done);
// Simulate disconnect
queue.isReady().then(function() {
queue.isReady().then(() => {
queue.client.stream.end();
queue.client.emit('error', new Error('ECONNRESET'));
@@ -47,10 +46,10 @@ describe('connection', function() {
});
});
it('should handle jobs added before and after a redis disconnect', function(done) {
var count = 0;
it('should handle jobs added before and after a redis disconnect', done => {
let count = 0;
queue
.process(function(job, jobDone) {
.process((job, jobDone) => {
if (count == 0) {
expect(job.data.foo).to.be.equal('bar');
jobDone();
@@ -62,30 +61,30 @@ describe('connection', function() {
})
.catch(done);
queue.on('completed', function() {
queue.on('completed', () => {
if (count === 1) {
queue.client.stream.end();
queue.client.emit('error', new Error('ECONNRESET'));
}
});
queue.isReady().then(function() {
queue.isReady().then(() => {
queue.add({ foo: 'bar' });
});
queue.on('error', function(/*err*/) {
queue.on('error', (/*err*/) => {
if (count === 1) {
queue.add({ foo: 'bar' });
}
});
});
it('should not close external connections', function() {
var client = new redis();
var subscriber = new redis();
it('should not close external connections', () => {
const client = new redis();
const subscriber = new redis();
var opts = {
createClient: function(type) {
const opts = {
createClient(type) {
switch (type) {
case 'client':
return client;
@@ -97,27 +96,27 @@ describe('connection', function() {
}
};
var testQueue = utils.buildQueue('external connections', opts);
const testQueue = utils.buildQueue('external connections', opts);
return testQueue
.isReady()
.then(function() {
.then(() => {
return testQueue.add({ foo: 'bar' });
})
.then(function() {
.then(() => {
expect(testQueue.client).to.be.eql(client);
expect(testQueue.eclient).to.be.eql(subscriber);
return testQueue.close();
})
.then(function() {
.then(() => {
expect(client.status).to.be.eql('ready');
expect(subscriber.status).to.be.eql('ready');
return Promise.all([client.quit(), subscriber.quit()]);
});
});
it('should fail if redis connection fails', function(done) {
it('should fail if redis connection fails', done => {
queue = utils.buildQueue('connection fail', {
redis: {
host: 'localhost',
@@ -126,10 +125,10 @@ describe('connection', function() {
});
queue.isReady().then(
function() {
() => {
done(new Error('Did not fail connecting to invalid redis instance'));
},
function(err) {
err => {
expect(err.code).to.be.eql('ECONNREFUSED');
queue.close().then(done, done);
}
+63 -64
View File
@@ -1,21 +1,20 @@
/*eslint-env node */
'use strict';
var utils = require('./utils');
var redis = require('ioredis');
var delay = require('delay');
var Queue = require('../');
var Job = require('../lib/job');
var expect = require('chai').expect;
const utils = require('./utils');
const redis = require('ioredis');
const delay = require('delay');
const Queue = require('../');
const Job = require('../lib/job');
const expect = require('chai').expect;
var _ = require('lodash');
const _ = require('lodash');
describe('events', function() {
var queue;
describe('events', () => {
let queue;
beforeEach(function() {
var client = new redis();
return client.flushdb().then(function() {
beforeEach(() => {
const client = new redis();
return client.flushdb().then(() => {
queue = utils.buildQueue('test events', {
settings: {
stalledInterval: 100,
@@ -26,109 +25,109 @@ describe('events', function() {
});
});
afterEach(function() {
afterEach(() => {
return queue.close();
});
it('should emit waiting when a job has been added', function(done) {
queue.on('waiting', function() {
it('should emit waiting when a job has been added', done => {
queue.on('waiting', () => {
done();
});
queue.on('registered:waiting', function() {
queue.on('registered:waiting', () => {
queue.add({ foo: 'bar' });
});
});
it('should emit global:waiting when a job has been added', function(done) {
queue.on('global:waiting', function() {
it('should emit global:waiting when a job has been added', done => {
queue.on('global:waiting', () => {
done();
});
queue.on('registered:global:waiting', function() {
queue.on('registered:global:waiting', () => {
queue.add({ foo: 'bar' });
});
});
it('should emit stalled when a job has been stalled', function(done) {
queue.on('completed', function(/*job*/) {
it('should emit stalled when a job has been stalled', done => {
queue.on('completed', (/*job*/) => {
done(new Error('should not have completed'));
});
queue.process(function(/*job*/) {
queue.process((/*job*/) => {
return delay(250);
});
queue.add({ foo: 'bar' });
var queue2 = utils.buildQueue('test events', {
const queue2 = utils.buildQueue('test events', {
settings: {
stalledInterval: 100
}
});
queue2.on('stalled', function(/*job*/) {
queue2.on('stalled', (/*job*/) => {
queue2.close().then(done);
});
queue.on('active', function() {
queue.on('active', () => {
queue2.startMoveUnlockedJobsToWait();
queue.close(true);
});
});
it('should emit global:stalled when a job has been stalled', function(done) {
queue.on('completed', function(/*job*/) {
it('should emit global:stalled when a job has been stalled', done => {
queue.on('completed', (/*job*/) => {
done(new Error('should not have completed'));
});
queue.process(function(/*job*/) {
queue.process((/*job*/) => {
return delay(250);
});
queue.add({ foo: 'bar' });
var queue2 = utils.buildQueue('test events', {
const queue2 = utils.buildQueue('test events', {
settings: {
stalledInterval: 100
}
});
queue2.on('global:stalled', function(/*job*/) {
queue2.on('global:stalled', (/*job*/) => {
queue2.close().then(done);
});
queue.on('active', function() {
queue.on('active', () => {
queue2.startMoveUnlockedJobsToWait();
queue.close(true);
});
});
it('emits waiting event when a job is added', function(done) {
var queue = utils.buildQueue();
it('emits waiting event when a job is added', done => {
const queue = utils.buildQueue();
queue.once('waiting', function(jobId) {
Job.fromId(queue, jobId).then(function(job) {
queue.once('waiting', jobId => {
Job.fromId(queue, jobId).then(job => {
expect(job.data.foo).to.be.equal('bar');
queue.close().then(done);
});
});
queue.once('registered:waiting', function() {
queue.once('registered:waiting', () => {
queue.add({ foo: 'bar' });
});
});
it('emits drained and global:drained event when all jobs have been processed', function(done) {
var queue = utils.buildQueue('event drained', {
it('emits drained and global:drained event when all jobs have been processed', done => {
const queue = utils.buildQueue('event drained', {
settings: { drainDelay: 1 }
});
queue.process(function(job, done) {
queue.process((job, done) => {
done();
});
var drainedCallback = _.after(2, function() {
queue.getJobCountByTypes('completed').then(function(completed) {
const drainedCallback = _.after(2, () => {
queue.getJobCountByTypes('completed').then(completed => {
expect(completed).to.be.equal(2);
return queue.close().then(done);
});
@@ -141,61 +140,61 @@ describe('events', function() {
queue.add({ foo: 'baz' });
});
it('should emit an event when a new message is added to the queue', function(done) {
var client = new redis(6379, '127.0.0.1', {});
it('should emit an event when a new message is added to the queue', done => {
const client = new redis(6379, '127.0.0.1', {});
client.select(0);
var queue = new Queue('test pub sub');
queue.on('waiting', function(jobId) {
const queue = new Queue('test pub sub');
queue.on('waiting', jobId => {
expect(parseInt(jobId, 10)).to.be.eql(1);
client.quit();
done();
});
queue.once('registered:waiting', function() {
queue.once('registered:waiting', () => {
queue.add({ test: 'stuff' });
});
});
it('should emit an event when a job becomes active', function(done) {
var queue = utils.buildQueue();
queue.process(function(job, jobDone) {
it('should emit an event when a job becomes active', done => {
const queue = utils.buildQueue();
queue.process((job, jobDone) => {
jobDone();
});
queue.add({});
queue.once('active', function() {
queue.once('completed', function() {
queue.once('active', () => {
queue.once('completed', () => {
queue.close().then(done);
});
});
});
it('should listen to global events', function(done) {
var queue1 = utils.buildQueue();
var queue2 = utils.buildQueue();
queue1.process(function(job, jobDone) {
it('should listen to global events', done => {
const queue1 = utils.buildQueue();
const queue2 = utils.buildQueue();
queue1.process((job, jobDone) => {
jobDone();
});
var state;
queue2.on('global:waiting', function() {
let state;
queue2.on('global:waiting', () => {
expect(state).to.be.undefined;
state = 'waiting';
});
queue2.once('registered:global:waiting', function() {
queue2.once('global:active', function() {
queue2.once('registered:global:waiting', () => {
queue2.once('global:active', () => {
expect(state).to.be.equal('waiting');
state = 'active';
});
});
queue2.once('registered:global:active', function() {
queue2.once('global:completed', function() {
queue2.once('registered:global:active', () => {
queue2.once('global:completed', () => {
expect(state).to.be.equal('active');
queue1.close().then(function() {
queue1.close().then(() => {
queue2.close().then(done);
});
});
});
queue2.once('registered:global:completed', function() {
queue2.once('registered:global:completed', () => {
queue1.add({});
});
});
+66 -67
View File
@@ -1,24 +1,23 @@
/*eslint-env node */
'use strict';
var redis = require('ioredis');
const redis = require('ioredis');
var utils = require('./utils');
var expect = require('chai').expect;
const utils = require('./utils');
const expect = require('chai').expect;
var _ = require('lodash');
const _ = require('lodash');
describe('Jobs getters', function() {
this.timeout(12000);
var queue;
var client;
let queue;
let client;
beforeEach(function() {
beforeEach(() => {
client = new redis();
return client.flushdb();
});
beforeEach(function() {
beforeEach(() => {
queue = utils.buildQueue();
});
@@ -28,20 +27,20 @@ describe('Jobs getters', function() {
);
return queue
.clean(1000)
.then(function() {
.then(() => {
return queue.close();
})
.then(function() {
.then(() => {
return client.quit();
});
});
it('should get waiting jobs', function() {
it('should get waiting jobs', () => {
return Promise.all([
queue.add({ foo: 'bar' }),
queue.add({ baz: 'qux' })
]).then(function() {
return queue.getWaiting().then(function(jobs) {
]).then(() => {
return queue.getWaiting().then(jobs => {
expect(jobs).to.be.a('array');
expect(jobs.length).to.be.equal(2);
expect(jobs[0].data.foo).to.be.equal('bar');
@@ -50,13 +49,13 @@ describe('Jobs getters', function() {
});
});
it('should get paused jobs', function() {
return queue.pause().then(function() {
it('should get paused jobs', () => {
return queue.pause().then(() => {
return Promise.all([
queue.add({ foo: 'bar' }),
queue.add({ baz: 'qux' })
]).then(function() {
return queue.getWaiting().then(function(jobs) {
]).then(() => {
return queue.getWaiting().then(jobs => {
expect(jobs).to.be.a('array');
expect(jobs.length).to.be.equal(2);
expect(jobs[0].data.foo).to.be.equal('bar');
@@ -66,9 +65,9 @@ describe('Jobs getters', function() {
});
});
it('should get active jobs', function(done) {
queue.process(function(job, jobDone) {
queue.getActive().then(function(jobs) {
it('should get active jobs', done => {
queue.process((job, jobDone) => {
queue.getActive().then(jobs => {
expect(jobs).to.be.a('array');
expect(jobs.length).to.be.equal(1);
expect(jobs[0].data.foo).to.be.equal('bar');
@@ -80,10 +79,10 @@ describe('Jobs getters', function() {
queue.add({ foo: 'bar' });
});
it('should get a specific job', function(done) {
var data = { foo: 'sup!' };
queue.add(data).then(function(job) {
queue.getJob(job.id).then(function(returnedJob) {
it('should get a specific job', done => {
const data = { foo: 'sup!' };
queue.add(data).then(job => {
queue.getJob(job.id).then(returnedJob => {
expect(returnedJob.data).to.eql(data);
expect(returnedJob.id).to.be.eql(job.id);
done();
@@ -91,18 +90,18 @@ describe('Jobs getters', function() {
});
});
it('should get completed jobs', function(done) {
var counter = 2;
it('should get completed jobs', done => {
let counter = 2;
queue.process(function(job, jobDone) {
queue.process((job, jobDone) => {
jobDone();
});
queue.on('completed', function() {
queue.on('completed', () => {
counter--;
if (counter === 0) {
queue.getCompleted().then(function(jobs) {
queue.getCompleted().then(jobs => {
expect(jobs).to.be.a('array');
// We need a "empty completed" kind of function.
//expect(jobs.length).to.be.equal(2);
@@ -115,18 +114,18 @@ describe('Jobs getters', function() {
queue.add({ baz: 'qux' });
});
it('should get failed jobs', function(done) {
var counter = 2;
it('should get failed jobs', done => {
let counter = 2;
queue.process(function(job, jobDone) {
queue.process((job, jobDone) => {
jobDone(new Error('Forced error'));
});
queue.on('failed', function() {
queue.on('failed', () => {
counter--;
if (counter === 0) {
queue.getFailed().then(function(jobs) {
queue.getFailed().then(jobs => {
expect(jobs).to.be.a('array');
done();
});
@@ -137,18 +136,18 @@ describe('Jobs getters', function() {
queue.add({ baz: 'qux' });
});
it('fails jobs that exceed their specified timeout', function(done) {
queue.process(function(job, jobDone) {
it('fails jobs that exceed their specified timeout', done => {
queue.process((job, jobDone) => {
setTimeout(jobDone, 200);
});
queue.on('failed', function(job, error) {
queue.on('failed', (job, error) => {
expect(error.message).to.contain('timed out');
done();
});
queue.on('completed', function() {
var error = new Error('The job should have timed out');
queue.on('completed', () => {
const error = new Error('The job should have timed out');
done(error);
});
@@ -160,17 +159,17 @@ describe('Jobs getters', function() {
);
});
it('should return all completed jobs when not setting start/end', function(done) {
queue.process(function(job, completed) {
it('should return all completed jobs when not setting start/end', done => {
queue.process((job, completed) => {
completed();
});
queue.on(
'completed',
_.after(3, function() {
_.after(3, () => {
queue
.getJobs('completed')
.then(function(jobs) {
.then(jobs => {
expect(jobs)
.to.be.an('array')
.that.have.length(3);
@@ -192,17 +191,17 @@ describe('Jobs getters', function() {
queue.add({ foo: 3 });
});
it('should return all failed jobs when not setting start/end', function(done) {
queue.process(function(job, completed) {
it('should return all failed jobs when not setting start/end', done => {
queue.process((job, completed) => {
completed(new Error('error'));
});
queue.on(
'failed',
_.after(3, function() {
_.after(3, () => {
queue
.getJobs('failed')
.then(function(jobs) {
.then(jobs => {
expect(jobs)
.to.be.an('array')
.that.has.length(3);
@@ -224,17 +223,17 @@ describe('Jobs getters', function() {
queue.add({ foo: 3 });
});
it('should return subset of jobs when setting positive range', function(done) {
queue.process(function(job, completed) {
it('should return subset of jobs when setting positive range', done => {
queue.process((job, completed) => {
completed();
});
queue.on(
'completed',
_.after(3, function() {
_.after(3, () => {
queue
.getJobs('completed', 1, 2, true)
.then(function(jobs) {
.then(jobs => {
expect(jobs)
.to.be.an('array')
.that.has.length(2);
@@ -252,25 +251,25 @@ describe('Jobs getters', function() {
queue
.add({ foo: 1 })
.then(function() {
.then(() => {
return queue.add({ foo: 2 });
})
.then(function() {
.then(() => {
return queue.add({ foo: 3 });
});
});
it('should return subset of jobs when setting a negative range', function(done) {
queue.process(function(job, completed) {
it('should return subset of jobs when setting a negative range', done => {
queue.process((job, completed) => {
completed();
});
queue.on(
'completed',
_.after(3, function() {
_.after(3, () => {
queue
.getJobs('completed', -3, -1, true)
.then(function(jobs) {
.then(jobs => {
expect(jobs)
.to.be.an('array')
.that.has.length(3);
@@ -288,17 +287,17 @@ describe('Jobs getters', function() {
queue.add({ foo: 3 });
});
it('should return subset of jobs when range overflows', function(done) {
queue.process(function(job, completed) {
it('should return subset of jobs when range overflows', done => {
queue.process((job, completed) => {
completed();
});
queue.on(
'completed',
_.after(3, function() {
_.after(3, () => {
queue
.getJobs('completed', -300, 99999, true)
.then(function(jobs) {
.then(jobs => {
expect(jobs)
.to.be.an('array')
.that.has.length(3);
@@ -316,9 +315,9 @@ describe('Jobs getters', function() {
queue.add({ foo: 3 });
});
it('should return jobs for multiple types', function(done) {
var counter = 0;
queue.process(function(/*job*/) {
it('should return jobs for multiple types', done => {
let counter = 0;
queue.process((/*job*/) => {
counter++;
if (counter == 2) {
return queue.pause();
@@ -327,10 +326,10 @@ describe('Jobs getters', function() {
queue.on(
'completed',
_.after(2, function() {
_.after(2, () => {
queue
.getJobs(['completed', 'paused'])
.then(function(jobs) {
.then(jobs => {
expect(jobs).to.be.an('array');
expect(jobs).to.have.length(3);
done();
+284 -293
View File
File diff suppressed because it is too large Load Diff
+109 -116
View File
@@ -1,31 +1,30 @@
/*eslint-env node */
'use strict';
var Queue = require('../');
const Queue = require('../');
var expect = require('chai').expect;
var redis = require('ioredis');
var utils = require('./utils');
var delay = require('delay');
const expect = require('chai').expect;
const redis = require('ioredis');
const utils = require('./utils');
const delay = require('delay');
describe('.pause', function() {
var client;
beforeEach(function() {
describe('.pause', () => {
let client;
beforeEach(() => {
client = new redis();
return client.flushdb();
});
afterEach(function() {
afterEach(() => {
return client.quit();
});
it('should pause a queue until resumed', function() {
var ispaused = false,
it('should pause a queue until resumed', () => {
let ispaused = false,
counter = 2;
return utils.newQueue().then(function(queue) {
var resultPromise = new Promise(function(resolve) {
queue.process(function(job, jobDone) {
return utils.newQueue().then(queue => {
const resultPromise = new Promise(resolve => {
queue.process((job, jobDone) => {
expect(ispaused).to.be.eql(false);
expect(job.data.foo).to.be.equal('paused');
jobDone();
@@ -39,14 +38,14 @@ describe('.pause', function() {
return Promise.all([
queue
.pause()
.then(function() {
.then(() => {
ispaused = true;
return queue.add({ foo: 'paused' });
})
.then(function() {
.then(() => {
return queue.add({ foo: 'paused' });
})
.then(function() {
.then(() => {
ispaused = false;
return queue.resume();
}),
@@ -55,13 +54,13 @@ describe('.pause', function() {
});
});
it('should be able to pause a running queue and emit relevant events', function(done) {
var ispaused = false,
it('should be able to pause a running queue and emit relevant events', done => {
let ispaused = false,
isresumed = true,
first = true;
utils.newQueue().then(function(queue) {
queue.process(function(job) {
utils.newQueue().then(queue => {
queue.process(job => {
expect(ispaused).to.be.eql(false);
expect(job.data.foo).to.be.equal('paused');
@@ -78,32 +77,32 @@ describe('.pause', function() {
queue.add({ foo: 'paused' });
queue.add({ foo: 'paused' });
queue.on('paused', function() {
queue.on('paused', () => {
ispaused = false;
queue.resume().catch(function(/*err*/) {
queue.resume().catch((/*err*/) => {
// Swallow error.
});
});
queue.on('resumed', function() {
queue.on('resumed', () => {
isresumed = true;
});
});
});
it('should pause the queue locally', function(done) {
var counter = 2;
it('should pause the queue locally', done => {
let counter = 2;
var queue = utils.buildQueue();
const queue = utils.buildQueue();
queue
.pause(true /* Local */)
.then(function() {
.then(() => {
// Add the worker after the queue is in paused mode since the normal behavior is to pause
// it after the current lock expires. This way, we can ensure there isn't a lock already
// to test that pausing behavior works.
queue
.process(function(job, jobDone) {
.process((job, jobDone) => {
expect(queue.paused).not.to.be.ok;
jobDone();
counter--;
@@ -113,13 +112,13 @@ describe('.pause', function() {
})
.catch(done);
})
.then(function() {
.then(() => {
return queue.add({ foo: 'paused' });
})
.then(function() {
.then(() => {
return queue.add({ foo: 'paused' });
})
.then(function() {
.then(() => {
expect(counter).to.be.eql(2);
expect(queue.paused).to.be.ok; // Parameter should exist.
return queue.resume(true /* Local */);
@@ -127,18 +126,18 @@ describe('.pause', function() {
.catch(done);
});
it('should wait until active jobs are finished before resolving pause', function(done) {
var queue = utils.buildQueue();
var startProcessing = new Promise(function(resolve) {
queue.process(function(/*job*/) {
it('should wait until active jobs are finished before resolving pause', done => {
const queue = utils.buildQueue();
const startProcessing = new Promise(resolve => {
queue.process((/*job*/) => {
resolve();
return delay(200);
});
});
queue.isReady().then(function() {
var jobs = [];
for (var i = 0; i < 10; i++) {
queue.isReady().then(() => {
const jobs = [];
for (let i = 0; i < 10; i++) {
jobs.push(queue.add(i));
}
//
@@ -146,48 +145,48 @@ describe('.pause', function() {
//
jobs.push(startProcessing);
Promise.all(jobs)
.then(function() {
.then(() => {
return queue
.pause(true)
.then(function() {
var active = queue
.then(() => {
const active = queue
.getJobCountByTypes(['active'])
.then(function(count) {
.then(count => {
expect(count).to.be.eql(0);
expect(queue.paused).to.be.ok;
return null;
});
// One job from the 10 posted above will be processed, so we expect 9 jobs pending
var paused = queue
const paused = queue
.getJobCountByTypes(['delayed', 'wait'])
.then(function(count) {
.then(count => {
expect(count).to.be.eql(9);
return null;
});
return Promise.all([active, paused]);
})
.then(function() {
.then(() => {
return queue.add({});
})
.then(function() {
var active = queue
.then(() => {
const active = queue
.getJobCountByTypes(['active'])
.then(function(count) {
.then(count => {
expect(count).to.be.eql(0);
return null;
});
var paused = queue
const paused = queue
.getJobCountByTypes(['paused', 'wait', 'delayed'])
.then(function(count) {
.then(count => {
expect(count).to.be.eql(10);
return null;
});
return Promise.all([active, paused]);
})
.then(function() {
.then(() => {
return queue.close().then(done, done);
});
})
@@ -195,18 +194,18 @@ describe('.pause', function() {
});
});
it('should pause the queue locally when more than one worker is active', function() {
var queue1 = utils.buildQueue('pause-queue');
var queue1IsProcessing = new Promise(function(resolve) {
queue1.process(function(job, jobDone) {
it('should pause the queue locally when more than one worker is active', () => {
const queue1 = utils.buildQueue('pause-queue');
const queue1IsProcessing = new Promise(resolve => {
queue1.process((job, jobDone) => {
resolve();
setTimeout(jobDone, 200);
});
});
var queue2 = utils.buildQueue('pause-queue');
var queue2IsProcessing = new Promise(function(resolve) {
queue2.process(function(job, jobDone) {
const queue2 = utils.buildQueue('pause-queue');
const queue2IsProcessing = new Promise(resolve => {
queue2.process((job, jobDone) => {
resolve();
setTimeout(jobDone, 200);
});
@@ -217,43 +216,37 @@ describe('.pause', function() {
queue1.add(3);
queue1.add(4);
return Promise.all([queue1IsProcessing, queue2IsProcessing]).then(
function() {
return Promise.all([
queue1.pause(true /* local */),
queue2.pause(true /* local */)
]).then(function() {
var active = queue1
.getJobCountByTypes(['active'])
.then(function(count) {
expect(count).to.be.eql(0);
});
var pending = queue1
.getJobCountByTypes(['wait'])
.then(function(count) {
expect(count).to.be.eql(2);
});
var completed = queue1
.getJobCountByTypes(['completed'])
.then(function(count) {
expect(count).to.be.eql(2);
});
return Promise.all([active, pending, completed]).then(function() {
return Promise.all([queue1.close(), queue2.close()]);
});
return Promise.all([queue1IsProcessing, queue2IsProcessing]).then(() => {
return Promise.all([
queue1.pause(true /* local */),
queue2.pause(true /* local */)
]).then(() => {
const active = queue1.getJobCountByTypes(['active']).then(count => {
expect(count).to.be.eql(0);
});
}
);
const pending = queue1.getJobCountByTypes(['wait']).then(count => {
expect(count).to.be.eql(2);
});
const completed = queue1
.getJobCountByTypes(['completed'])
.then(count => {
expect(count).to.be.eql(2);
});
return Promise.all([active, pending, completed]).then(() => {
return Promise.all([queue1.close(), queue2.close()]);
});
});
});
});
it('should wait for blocking job retrieval to complete before pausing locally', function() {
var queue = utils.buildQueue();
it('should wait for blocking job retrieval to complete before pausing locally', () => {
const queue = utils.buildQueue();
var startsProcessing = new Promise(function(resolve) {
queue.process(function(/*job*/) {
const startsProcessing = new Promise(resolve => {
queue.process((/*job*/) => {
resolve();
return delay(200);
});
@@ -261,31 +254,31 @@ describe('.pause', function() {
return queue
.add(1)
.then(function() {
.then(() => {
return startsProcessing;
})
.then(function() {
.then(() => {
return queue.pause(true);
})
.then(function() {
.then(() => {
return queue.add(2);
})
.then(function() {
var active = queue.getJobCountByTypes(['active']).then(function(count) {
.then(() => {
const active = queue.getJobCountByTypes(['active']).then(count => {
expect(count).to.be.eql(0);
});
var pending = queue.getJobCountByTypes(['wait']).then(function(count) {
const pending = queue.getJobCountByTypes(['wait']).then(count => {
expect(count).to.be.eql(1);
});
var completed = queue
const completed = queue
.getJobCountByTypes(['completed'])
.then(function(count) {
.then(count => {
expect(count).to.be.eql(1);
});
return Promise.all([active, pending, completed]).then(function() {
return Promise.all([active, pending, completed]).then(() => {
return queue.close();
});
});
@@ -293,19 +286,19 @@ describe('.pause', function() {
it('pauses fast when queue is drained', function(done) {
this.timeout(10000);
var queue = new Queue('test');
const queue = new Queue('test');
queue.process(function(/*job*/) {
queue.process((/*job*/) => {
Promise.resolve();
});
queue.add({});
queue.on('drained', function() {
delay(500).then(function() {
var start = new Date().getTime();
return queue.pause(true).finally(function() {
var finish = new Date().getTime();
queue.on('drained', () => {
delay(500).then(() => {
const start = new Date().getTime();
return queue.pause(true).finally(() => {
const finish = new Date().getTime();
expect(finish - start).to.be.lt(1000);
queue.close().then(done, done);
});
@@ -315,13 +308,13 @@ describe('.pause', function() {
it('should not processed delayed jobs', function(done) {
this.timeout(5000);
var queue = new Queue('pause-test');
const queue = new Queue('pause-test');
queue.process(function() {
queue.process(() => {
done(new Error('should not process delayed jobs in paused queue.'));
});
queue.pause().then(function() {
queue.pause().then(() => {
queue
.add(
{},
@@ -329,19 +322,19 @@ describe('.pause', function() {
delay: 500
}
)
.then(function() {
.then(() => {
return queue.getJobCounts();
})
.then(function(counts) {
.then(counts => {
expect(counts).to.have.property('paused', 0);
expect(counts).to.have.property('waiting', 0);
expect(counts).to.have.property('delayed', 1);
return delay(1000);
})
.then(function() {
.then(() => {
return queue.getJobCounts();
})
.then(function(counts) {
.then(counts => {
expect(counts).to.have.property('paused', 1);
expect(counts).to.have.property('waiting', 0);
done();
+565 -573
View File
File diff suppressed because it is too large Load Diff
+35 -35
View File
@@ -1,18 +1,18 @@
/*eslint-env node */
'use strict';
var expect = require('chai').expect;
var utils = require('./utils');
var redis = require('ioredis');
var _ = require('lodash');
const expect = require('chai').expect;
const utils = require('./utils');
const redis = require('ioredis');
const _ = require('lodash');
const assert = require('assert');
describe('Rate limiter', function() {
var queue;
var client;
describe('Rate limiter', () => {
let queue;
let client;
beforeEach(function() {
beforeEach(() => {
client = new redis();
return client.flushdb().then(function() {
return client.flushdb().then(() => {
queue = utils.buildQueue('test rate limiter', {
limiter: {
max: 1,
@@ -23,13 +23,13 @@ describe('Rate limiter', function() {
});
});
afterEach(function() {
return queue.close().then(function() {
afterEach(() => {
return queue.close().then(() => {
return client.quit();
});
});
it('should throw exception if missing duration option', function(done) {
it('should throw exception if missing duration option', done => {
try {
utils.buildQueue('rate limiter fail', {
limiter: {
@@ -42,7 +42,7 @@ describe('Rate limiter', function() {
}
});
it('should throw exception if missing max option', function(done) {
it('should throw exception if missing max option', done => {
try {
utils.buildQueue('rate limiter fail', {
limiter: {
@@ -55,24 +55,24 @@ describe('Rate limiter', function() {
}
});
it('should obey the rate limit', function(done) {
var startTime = new Date().getTime();
var numJobs = 4;
it('should obey the rate limit', done => {
const startTime = new Date().getTime();
const numJobs = 4;
queue.process(function() {
queue.process(() => {
return Promise.resolve();
});
for (var i = 0; i < numJobs; i++) {
for (let i = 0; i < numJobs; i++) {
queue.add({});
}
queue.on(
'completed',
// after every job has been completed
_.after(numJobs, function() {
_.after(numJobs, () => {
try {
var timeDiff = new Date().getTime() - startTime;
const timeDiff = new Date().getTime() - startTime;
expect(timeDiff).to.be.above((numJobs - 1) * 1000);
done();
} catch (err) {
@@ -81,20 +81,20 @@ describe('Rate limiter', function() {
})
);
queue.on('failed', function(err) {
queue.on('failed', err => {
done(err);
});
});
it('should put a job into the delayed queue when limit is hit', function() {
var newQueue = utils.buildQueue('test rate limiter', {
it('should put a job into the delayed queue when limit is hit', () => {
const newQueue = utils.buildQueue('test rate limiter', {
limiter: {
max: 1,
duration: 1000
}
});
queue.on('failed', function(e) {
queue.on('failed', e => {
assert.fail(e);
});
@@ -103,22 +103,22 @@ describe('Rate limiter', function() {
newQueue.add({}),
newQueue.add({}),
newQueue.add({})
]).then(function() {
]).then(() => {
Promise.all([
newQueue.getNextJob({}),
newQueue.getNextJob({}),
newQueue.getNextJob({}),
newQueue.getNextJob({})
]).then(function() {
return queue.getDelayedCount().then(function(delayedCount) {
]).then(() => {
return queue.getDelayedCount().then(delayedCount => {
expect(delayedCount).to.eq(3);
});
});
});
});
it('should not put a job into the delayed queue when discard is true', function() {
var newQueue = utils.buildQueue('test rate limiter', {
it('should not put a job into the delayed queue when discard is true', () => {
const newQueue = utils.buildQueue('test rate limiter', {
limiter: {
max: 1,
duration: 1000,
@@ -126,7 +126,7 @@ describe('Rate limiter', function() {
}
});
newQueue.on('failed', function(e) {
newQueue.on('failed', e => {
assert.fail(e);
});
return Promise.all([
@@ -134,16 +134,16 @@ describe('Rate limiter', function() {
newQueue.add({}),
newQueue.add({}),
newQueue.add({})
]).then(function() {
]).then(() => {
Promise.all([
newQueue.getNextJob({}),
newQueue.getNextJob({}),
newQueue.getNextJob({}),
newQueue.getNextJob({})
]).then(function() {
return newQueue.getDelayedCount().then(function(delayedCount) {
]).then(() => {
return newQueue.getDelayedCount().then(delayedCount => {
expect(delayedCount).to.eq(0);
return newQueue.getActiveCount().then(function(waitingCount) {
return newQueue.getActiveCount().then(waitingCount => {
expect(waitingCount).to.eq(1);
});
});
+176 -176
View File
@@ -1,27 +1,26 @@
/*eslint-env node */
'use strict';
var expect = require('chai').expect;
var utils = require('./utils');
var sinon = require('sinon');
var redis = require('ioredis');
var moment = require('moment');
var _ = require('lodash');
const expect = require('chai').expect;
const utils = require('./utils');
const sinon = require('sinon');
const redis = require('ioredis');
const moment = require('moment');
const _ = require('lodash');
var ONE_SECOND = 1000;
var ONE_MINUTE = 60 * ONE_SECOND;
var ONE_HOUR = 60 * ONE_MINUTE;
var ONE_DAY = 24 * ONE_HOUR;
var MAX_INT = 2147483647;
const ONE_SECOND = 1000;
const ONE_MINUTE = 60 * ONE_SECOND;
const ONE_HOUR = 60 * ONE_MINUTE;
const ONE_DAY = 24 * ONE_HOUR;
const MAX_INT = 2147483647;
describe('repeat', function() {
var queue;
var client;
describe('repeat', () => {
let queue;
let client;
beforeEach(function() {
this.clock = sinon.useFakeTimers();
client = new redis();
return client.flushdb().then(function() {
return client.flushdb().then(() => {
queue = utils.buildQueue('repeat', {
settings: {
guardInterval: MAX_INT,
@@ -35,31 +34,36 @@ describe('repeat', function() {
afterEach(function() {
this.clock.restore();
return queue.close().then(function() {
return queue.close().then(() => {
return client.quit();
});
});
it('should create multiple jobs if they have the same cron pattern', function(done) {
var cron = '*/10 * * * * *';
var customJobIds = ['customjobone', 'customjobtwo'];
it('should create multiple jobs if they have the same cron pattern', done => {
const cron = '*/10 * * * * *';
const customJobIds = ['customjobone', 'customjobtwo'];
Promise.all([
queue.add({}, { jobId: customJobIds[0], repeat: { cron: cron } }),
queue.add({}, { jobId: customJobIds[1], repeat: { cron: cron } })
queue.add({}, { jobId: customJobIds[0], repeat: { cron } }),
queue.add({}, { jobId: customJobIds[1], repeat: { cron } })
])
.then(function() {
.then(() => {
return queue.count();
})
.then(function(count) {
.then(count => {
expect(count).to.be.eql(2);
done();
})
.catch(done);
});
it('should get repeatable jobs with different cron pattern', function(done) {
var crons = ['10 * * * * *', '2 10 * * * *', '1 * * 5 * *', '2 * * 4 * *'];
it('should get repeatable jobs with different cron pattern', done => {
const crons = [
'10 * * * * *',
'2 10 * * * *',
'1 * * 5 * *',
'2 * * 4 * *'
];
Promise.all([
queue.add('first', {}, { repeat: { cron: crons[0], endDate: 12345 } }),
@@ -75,19 +79,19 @@ describe('repeat', function() {
{ repeat: { cron: crons[3], tz: 'Africa/Accra' } }
)
])
.then(function() {
.then(() => {
return queue.getRepeatableCount();
})
.then(function(count) {
.then(count => {
expect(count).to.be.eql(4);
return queue.getRepeatableJobs(0, -1, true);
})
.then(function(jobs) {
return jobs.sort(function(a, b) {
.then(jobs => {
return jobs.sort((a, b) => {
return crons.indexOf(a.cron) > crons.indexOf(b.cron);
});
})
.then(function(jobs) {
.then(jobs => {
expect(jobs)
.to.be.and.an('array')
.and.have.length(4)
@@ -133,24 +137,24 @@ describe('repeat', function() {
});
it('should repeat every 2 seconds', function(done) {
var _this = this;
var date = new Date('2017-02-07 9:24:00');
const _this = this;
const date = new Date('2017-02-07 9:24:00');
this.clock.tick(date.getTime());
var nextTick = 2 * ONE_SECOND + 500;
const nextTick = 2 * ONE_SECOND + 500;
queue
.add('repeat', { foo: 'bar' }, { repeat: { cron: '*/2 * * * * *' } })
.then(function() {
.then(() => {
_this.clock.tick(nextTick);
});
queue.process('repeat', function() {
queue.process('repeat', () => {
// dummy
});
var prev;
var counter = 0;
queue.on('completed', function(job) {
let prev;
let counter = 0;
queue.on('completed', job => {
_this.clock.tick(nextTick);
if (prev) {
expect(prev.timestamp).to.be.lt(job.timestamp);
@@ -165,11 +169,11 @@ describe('repeat', function() {
});
it('should repeat every 2 seconds with startDate in future', function(done) {
var _this = this;
var date = new Date('2017-02-07 9:24:00');
const _this = this;
const date = new Date('2017-02-07 9:24:00');
this.clock.tick(date.getTime());
var nextTick = 2 * ONE_SECOND + 500;
var delay = 5 * ONE_SECOND + 500;
const nextTick = 2 * ONE_SECOND + 500;
const delay = 5 * ONE_SECOND + 500;
queue
.add(
@@ -182,17 +186,17 @@ describe('repeat', function() {
}
}
)
.then(function() {
.then(() => {
_this.clock.tick(nextTick + delay);
});
queue.process('repeat', function() {
queue.process('repeat', () => {
// dummy
});
var prev;
var counter = 0;
queue.on('completed', function(job) {
let prev;
let counter = 0;
queue.on('completed', job => {
_this.clock.tick(nextTick);
if (prev) {
expect(prev.timestamp).to.be.lt(job.timestamp);
@@ -207,10 +211,10 @@ describe('repeat', function() {
});
it('should repeat every 2 seconds with startDate in past', function(done) {
var _this = this;
var date = new Date('2017-02-07 9:24:00');
const _this = this;
const date = new Date('2017-02-07 9:24:00');
this.clock.tick(date.getTime());
var nextTick = 2 * ONE_SECOND + 500;
const nextTick = 2 * ONE_SECOND + 500;
queue
.add(
@@ -223,17 +227,17 @@ describe('repeat', function() {
}
}
)
.then(function() {
.then(() => {
_this.clock.tick(nextTick);
});
queue.process('repeat', function() {
queue.process('repeat', () => {
// dummy
});
var prev;
var counter = 0;
queue.on('completed', function(job) {
let prev;
let counter = 0;
queue.on('completed', job => {
_this.clock.tick(nextTick);
if (prev) {
expect(prev.timestamp).to.be.lt(job.timestamp);
@@ -248,10 +252,10 @@ describe('repeat', function() {
});
it('should repeat once a day for 5 days', function(done) {
var _this = this;
var date = new Date('2017-05-05 13:12:00');
const _this = this;
const date = new Date('2017-05-05 13:12:00');
this.clock.tick(date.getTime());
var nextTick = ONE_DAY;
const nextTick = ONE_DAY;
queue
.add(
@@ -264,17 +268,17 @@ describe('repeat', function() {
}
}
)
.then(function() {
.then(() => {
_this.clock.tick(nextTick);
});
queue.process('repeat', function() {
queue.process('repeat', () => {
// Dummy
});
var prev;
var counter = 0;
queue.on('completed', function(job) {
let prev;
let counter = 0;
queue.on('completed', job => {
_this.clock.tick(nextTick);
if (prev) {
expect(prev.timestamp).to.be.lt(job.timestamp);
@@ -284,9 +288,9 @@ describe('repeat', function() {
counter++;
if (counter == 5) {
queue.getWaiting().then(function(jobs) {
queue.getWaiting().then(jobs => {
expect(jobs.length).to.be.eql(0);
queue.getDelayed().then(function(jobs) {
queue.getDelayed().then(jobs => {
expect(jobs.length).to.be.eql(0);
done();
});
@@ -296,32 +300,32 @@ describe('repeat', function() {
});
it('should repeat 7:th day every month at 9:25', function(done) {
var _this = this;
var date = new Date('2017-02-02 7:21:42');
const _this = this;
const date = new Date('2017-02-02 7:21:42');
this.clock.tick(date.getTime());
function nextTick() {
var now = moment();
var nextMonth = moment().add(1, 'months');
const now = moment();
const nextMonth = moment().add(1, 'months');
_this.clock.tick(nextMonth - now);
}
queue
.add('repeat', { foo: 'bar' }, { repeat: { cron: '* 25 9 7 * *' } })
.then(function() {
.then(() => {
nextTick();
});
queue.process('repeat', function(/*job*/) {
queue.process('repeat', (/*job*/) => {
// Dummy
});
var counter = 20;
var prev;
queue.on('completed', function(job) {
let counter = 20;
let prev;
queue.on('completed', job => {
if (prev) {
expect(prev.timestamp).to.be.lt(job.timestamp);
var diff = moment(job.timestamp).diff(
const diff = moment(job.timestamp).diff(
moment(prev.timestamp),
'months',
true
@@ -338,40 +342,40 @@ describe('repeat', function() {
});
});
it('should create two jobs with the same ids', function() {
var options = {
it('should create two jobs with the same ids', () => {
const options = {
repeat: {
cron: '0 1 * * *'
}
};
var p1 = queue.add({ foo: 'bar' }, options);
var p2 = queue.add({ foo: 'bar' }, options);
const p1 = queue.add({ foo: 'bar' }, options);
const p2 = queue.add({ foo: 'bar' }, options);
return Promise.all([p1, p2]).then(function(jobs) {
return Promise.all([p1, p2]).then(jobs => {
expect(jobs.length).to.be.eql(2);
expect(jobs[0].id).to.be.eql(jobs[1].id);
});
});
it('should allow removing a named repeatable job', function(done) {
var _this = this;
var date = new Date('2017-02-07 9:24:00');
const _this = this;
const date = new Date('2017-02-07 9:24:00');
this.clock.tick(date.getTime());
var nextTick = 2 * ONE_SECOND;
var repeat = { cron: '*/2 * * * * *' };
const nextTick = 2 * ONE_SECOND;
const repeat = { cron: '*/2 * * * * *' };
queue.add('remove', { foo: 'bar' }, { repeat: repeat }).then(function() {
queue.add('remove', { foo: 'bar' }, { repeat }).then(() => {
_this.clock.tick(nextTick);
});
queue.process('remove', function() {
queue.process('remove', () => {
counter++;
if (counter == 20) {
return queue.removeRepeatable('remove', repeat).then(function() {
return queue.removeRepeatable('remove', repeat).then(() => {
_this.clock.tick(nextTick);
return queue.getDelayed().then(function(delayed) {
return queue.getDelayed().then(delayed => {
expect(delayed).to.be.empty;
done();
return null;
@@ -382,9 +386,9 @@ describe('repeat', function() {
}
});
var prev;
var counter = 0;
queue.on('completed', function(job) {
let prev;
let counter = 0;
queue.on('completed', job => {
_this.clock.tick(nextTick);
if (prev) {
expect(prev.timestamp).to.be.lt(job.timestamp);
@@ -395,27 +399,25 @@ describe('repeat', function() {
});
it('should allow removing a customId repeatable job', function(done) {
var _this = this;
var date = new Date('2017-02-07 9:24:00');
const _this = this;
const date = new Date('2017-02-07 9:24:00');
this.clock.tick(date.getTime());
var nextTick = 2 * ONE_SECOND;
var repeat = { cron: '*/2 * * * * *' };
const nextTick = 2 * ONE_SECOND;
const repeat = { cron: '*/2 * * * * *' };
queue
.add({ foo: 'bar' }, { repeat: repeat, jobId: 'xxxx' })
.then(function() {
_this.clock.tick(nextTick);
});
queue.add({ foo: 'bar' }, { repeat: repeat, jobId: 'xxxx' }).then(() => {
_this.clock.tick(nextTick);
});
queue.process(function() {
queue.process(() => {
counter++;
if (counter == 20) {
return queue
.removeRepeatable(_.defaults({ jobId: 'xxxx' }, repeat))
.then(function() {
.then(() => {
_this.clock.tick(nextTick);
return queue.getDelayed().then(function(delayed) {
return queue.getDelayed().then(delayed => {
expect(delayed).to.be.empty;
done();
return null;
@@ -426,9 +428,9 @@ describe('repeat', function() {
}
});
var prev;
var counter = 0;
queue.on('completed', function(job) {
let prev;
let counter = 0;
queue.on('completed', job => {
_this.clock.tick(nextTick);
if (prev) {
expect(prev.timestamp).to.be.lt(job.timestamp);
@@ -439,57 +441,55 @@ describe('repeat', function() {
});
it('should not re-add a repeatable job after it has been removed', function() {
var _this = this;
var date = new Date('2017-02-07 9:24:00');
var nextTick = 2 * ONE_SECOND;
var repeat = { cron: '*/2 * * * * *' };
var nextRepeatableJob = queue.nextRepeatableJob;
const _this = this;
const date = new Date('2017-02-07 9:24:00');
const nextTick = 2 * ONE_SECOND;
const repeat = { cron: '*/2 * * * * *' };
const nextRepeatableJob = queue.nextRepeatableJob;
this.clock.tick(date.getTime());
var afterRemoved = new Promise(function(resolve) {
queue.process(function() {
const afterRemoved = new Promise(resolve => {
queue.process(() => {
queue.nextRepeatableJob = function() {
var args = arguments;
const args = arguments;
// In order to simulate race condition
// Make removeRepeatables happen any time after a moveToX is called
return queue
.removeRepeatable(_.defaults({ jobId: 'xxxx' }, repeat))
.then(function() {
.then(() => {
// nextRepeatableJob will now re-add the removed repeatable
return nextRepeatableJob.apply(queue, args);
})
.then(function(result) {
.then(result => {
resolve();
return result;
});
};
});
queue
.add({ foo: 'bar' }, { repeat: repeat, jobId: 'xxxx' })
.then(function() {
_this.clock.tick(nextTick);
});
queue.add({ foo: 'bar' }, { repeat: repeat, jobId: 'xxxx' }).then(() => {
_this.clock.tick(nextTick);
});
queue.on('completed', function() {
queue.on('completed', () => {
_this.clock.tick(nextTick);
});
});
return afterRemoved.then(function() {
return queue.getRepeatableJobs().then(function(jobs) {
return afterRemoved.then(() => {
return queue.getRepeatableJobs().then(jobs => {
// Repeatable job was recreated
expect(jobs.length).to.eql(0);
});
});
});
it('should allow adding a repeatable job after removing it', function() {
queue.process(function(/*job*/) {
it('should allow adding a repeatable job after removing it', () => {
queue.process((/*job*/) => {
// dummy
});
var repeat = {
const repeat = {
cron: '*/5 * * * *'
};
@@ -500,48 +500,48 @@ describe('repeat', function() {
data: '2'
},
{
repeat: repeat
repeat
}
)
.then(function() {
.then(() => {
return queue.getDelayed();
})
.then(function(delayed) {
.then(delayed => {
expect(delayed.length).to.be.eql(1);
})
.then(function() {
.then(() => {
return queue.removeRepeatable('myTestJob', repeat);
})
.then(function() {
.then(() => {
return queue.getDelayed();
})
.then(function(delayed) {
.then(delayed => {
expect(delayed.length).to.be.eql(0);
})
.then(function() {
.then(() => {
return queue.add(
'myTestJob',
{
data: '2'
},
{
repeat: repeat
repeat
}
);
})
.then(function() {
.then(() => {
return queue.getDelayed();
})
.then(function(delayed) {
.then(delayed => {
expect(delayed.length).to.be.eql(1);
});
});
it('should not repeat more than 5 times', function(done) {
var _this = this;
var date = new Date('2017-02-07 9:24:00');
const _this = this;
const date = new Date('2017-02-07 9:24:00');
this.clock.tick(date.getTime());
var nextTick = ONE_SECOND + 500;
const nextTick = ONE_SECOND + 500;
queue
.add(
@@ -549,20 +549,20 @@ describe('repeat', function() {
{ foo: 'bar' },
{ repeat: { limit: 5, cron: '*/1 * * * * *' } }
)
.then(function() {
.then(() => {
_this.clock.tick(nextTick);
});
queue.process('repeat', function() {
queue.process('repeat', () => {
// dummy
});
var counter = 0;
queue.on('completed', function() {
let counter = 0;
queue.on('completed', () => {
_this.clock.tick(nextTick);
counter++;
if (counter == 5) {
utils.sleep(nextTick * 2).then(function() {
utils.sleep(nextTick * 2).then(() => {
done();
}, nextTick * 2);
} else if (counter > 5) {
@@ -572,10 +572,10 @@ describe('repeat', function() {
});
it('should processes delayed jobs by priority', function(done) {
var _this = this;
var jobAdds = [];
var currentPriority = 1;
var nextTick = 1000;
const _this = this;
const jobAdds = [];
let currentPriority = 1;
const nextTick = 1000;
jobAdds.push(queue.add({ p: 1 }, { priority: 1, delay: nextTick * 3 }));
jobAdds.push(queue.add({ p: 2 }, { priority: 2, delay: nextTick * 2 }));
@@ -583,8 +583,8 @@ describe('repeat', function() {
_this.clock.tick(nextTick * 3);
Promise.all(jobAdds).then(function() {
queue.process(function(job, jobDone) {
Promise.all(jobAdds).then(() => {
queue.process((job, jobDone) => {
try {
expect(job.id).to.be.ok;
expect(job.data.p).to.be.eql(currentPriority++);
@@ -602,40 +602,40 @@ describe('repeat', function() {
// Skip test that only fails on travis
it.skip('should use ".every" as a valid interval', function(done) {
var _this = this;
var interval = ONE_SECOND * 2;
var date = new Date('2017-02-07 9:24:00');
const _this = this;
const interval = ONE_SECOND * 2;
const date = new Date('2017-02-07 9:24:00');
// Quantize time
var time = Math.floor(date.getTime() / interval) * interval;
const time = Math.floor(date.getTime() / interval) * interval;
this.clock.tick(time);
var nextTick = ONE_SECOND * 2 + 500;
const nextTick = ONE_SECOND * 2 + 500;
queue
.add('repeat m', { type: 'm' }, { repeat: { every: interval } })
.then(function() {
.then(() => {
return queue.add(
'repeat s',
{ type: 's' },
{ repeat: { every: interval } }
);
})
.then(function() {
.then(() => {
_this.clock.tick(nextTick);
});
queue.process('repeat m', function() {
queue.process('repeat m', () => {
// dummy
});
queue.process('repeat s', function() {
queue.process('repeat s', () => {
// dummy
});
var prevType;
var counter = 0;
queue.on('completed', function(job) {
let prevType;
let counter = 0;
queue.on('completed', job => {
_this.clock.tick(nextTick);
if (prevType) {
expect(prevType).to.not.be.eql(job.data.type);
@@ -648,7 +648,7 @@ describe('repeat', function() {
});
});
it('should throw an error when using .cron and .every simutaneously', function(done) {
it('should throw an error when using .cron and .every simutaneously', done => {
queue
.add(
'repeat',
@@ -656,10 +656,10 @@ describe('repeat', function() {
{ repeat: { every: 5000, cron: '*/1 * * * * *' } }
)
.then(
function() {
() => {
throw new Error('The error was not thrown');
},
function(err) {
err => {
expect(err.message).to.be.eql(
'Both .cron and .every options are defined for this repeatable job'
);
@@ -670,12 +670,12 @@ describe('repeat', function() {
// This tests works well locally but fails in travis for some unknown reason.
it.skip('should emit a waiting event when adding a repeatable job to the waiting list', function(done) {
var _this = this;
var date = new Date('2017-02-07 9:24:00');
const _this = this;
const date = new Date('2017-02-07 9:24:00');
this.clock.tick(date.getTime());
var nextTick = 2 * ONE_SECOND + 500;
const nextTick = 2 * ONE_SECOND + 500;
queue.on('waiting', function(jobId) {
queue.on('waiting', jobId => {
expect(jobId).to.be.equal(
'repeat:93168b0ea97b55fb5a8325e8c66e4300:' +
(date.getTime() + 2 * ONE_SECOND)
@@ -685,21 +685,21 @@ describe('repeat', function() {
queue
.add('repeat', { foo: 'bar' }, { repeat: { cron: '*/2 * * * * *' } })
.then(function() {
.then(() => {
_this.clock.tick(nextTick);
});
queue.process('repeat', function() {});
queue.process('repeat', () => {});
});
it('should have the right count value', function(done) {
var _this = this;
const _this = this;
queue.add({ foo: 'bar' }, { repeat: { every: 1000 } }).then(function() {
queue.add({ foo: 'bar' }, { repeat: { every: 1000 } }).then(() => {
_this.clock.tick(ONE_SECOND);
});
queue.process(function(job) {
queue.process(job => {
if (job.opts.repeat.count === 1) {
done();
} else {
+61 -62
View File
@@ -1,20 +1,19 @@
/*eslint-env node */
'use strict';
var expect = require('chai').expect;
var utils = require('./utils');
var redis = require('ioredis');
var _ = require('lodash');
var delay = require('delay');
var pReflect = require('p-reflect');
const expect = require('chai').expect;
const utils = require('./utils');
const redis = require('ioredis');
const _ = require('lodash');
const delay = require('delay');
const pReflect = require('p-reflect');
describe('sandboxed process', function() {
var queue;
var client;
describe('sandboxed process', () => {
let queue;
let client;
beforeEach(function() {
beforeEach(() => {
client = new redis();
return client.flushdb().then(function() {
return client.flushdb().then(() => {
queue = utils.buildQueue('test process', {
settings: {
guardInterval: 300000,
@@ -25,22 +24,22 @@ describe('sandboxed process', function() {
});
});
afterEach(function() {
afterEach(() => {
return queue
.close()
.then(function() {
.then(() => {
return client.flushall();
})
.then(function() {
.then(() => {
return client.quit();
});
});
it('should process and complete', function(done) {
var processFile = __dirname + '/fixtures/fixture_processor.js';
it('should process and complete', done => {
const processFile = __dirname + '/fixtures/fixture_processor.js';
queue.process(processFile);
queue.on('completed', function(job, value) {
queue.on('completed', (job, value) => {
try {
expect(job.data).to.be.eql({ foo: 'bar' });
expect(value).to.be.eql(42);
@@ -55,11 +54,11 @@ describe('sandboxed process', function() {
queue.add({ foo: 'bar' });
});
it('should process with named processor', function(done) {
var processFile = __dirname + '/fixtures/fixture_processor.js';
it('should process with named processor', done => {
const processFile = __dirname + '/fixtures/fixture_processor.js';
queue.process('foobar', processFile);
queue.on('completed', function(job, value) {
queue.on('completed', (job, value) => {
try {
expect(job.data).to.be.eql({ foo: 'bar' });
expect(value).to.be.eql(42);
@@ -74,16 +73,16 @@ describe('sandboxed process', function() {
queue.add('foobar', { foo: 'bar' });
});
it('should process with several named processors', function(done) {
var processFileFoo = __dirname + '/fixtures/fixture_processor_foo.js';
var processFileBar = __dirname + '/fixtures/fixture_processor_bar.js';
it('should process with several named processors', done => {
const processFileFoo = __dirname + '/fixtures/fixture_processor_foo.js';
const processFileBar = __dirname + '/fixtures/fixture_processor_bar.js';
queue.process('foo', processFileFoo);
queue.process('bar', processFileBar);
var count = 0;
queue.on('completed', function(job, value) {
var data, result, processFile, retainedLength;
let count = 0;
queue.on('completed', (job, value) => {
let data, result, processFile, retainedLength;
count++;
if (count == 1) {
data = { foo: 'bar' };
@@ -113,23 +112,23 @@ describe('sandboxed process', function() {
}
});
queue.add('foo', { foo: 'bar' }).then(function() {
delay(500).then(function() {
queue.add('foo', { foo: 'bar' }).then(() => {
delay(500).then(() => {
queue.add('bar', { bar: 'qux' });
});
});
queue.on('error', function(err) {
queue.on('error', err => {
console.error(err);
});
});
it('should process with concurrent processors', function(done) {
var after = _.after(4, function() {
it('should process with concurrent processors', done => {
const after = _.after(4, () => {
expect(queue.childPool.getAllFree().length).to.eql(4);
done();
});
queue.on('completed', function(job, value) {
queue.on('completed', (job, value) => {
try {
expect(value).to.be.eql(42);
expect(
@@ -147,17 +146,17 @@ describe('sandboxed process', function() {
queue.add({ foo: 'bar2' }),
queue.add({ foo: 'bar3' }),
queue.add({ foo: 'bar4' })
]).then(function() {
]).then(() => {
queue.process(4, __dirname + '/fixtures/fixture_processor_slow.js');
});
});
it('should reuse process with single processors', function(done) {
var after = _.after(4, function() {
it('should reuse process with single processors', done => {
const after = _.after(4, () => {
expect(queue.childPool.getAllFree().length).to.eql(1);
done();
});
queue.on('completed', function(job, value) {
queue.on('completed', (job, value) => {
try {
expect(value).to.be.eql(42);
expect(
@@ -175,15 +174,15 @@ describe('sandboxed process', function() {
queue.add({ foo: 'bar2' }),
queue.add({ foo: 'bar3' }),
queue.add({ foo: 'bar4' })
]).then(function() {
]).then(() => {
queue.process(__dirname + '/fixtures/fixture_processor_slow.js');
});
});
it('should process and complete using done', function(done) {
it('should process and complete using done', done => {
queue.process(__dirname + '/fixtures/fixture_processor_callback.js');
queue.on('completed', function(job, value) {
queue.on('completed', (job, value) => {
try {
expect(job.data).to.be.eql({ foo: 'bar' });
expect(value).to.be.eql(42);
@@ -198,10 +197,10 @@ describe('sandboxed process', function() {
queue.add({ foo: 'bar' });
});
it('should process and update progress', function(done) {
it('should process and update progress', done => {
queue.process(__dirname + '/fixtures/fixture_processor_progress.js');
queue.on('completed', function(job, value) {
queue.on('completed', (job, value) => {
try {
expect(job.data).to.be.eql({ foo: 'bar' });
expect(value).to.be.eql(37);
@@ -215,18 +214,18 @@ describe('sandboxed process', function() {
}
});
var progresses = [];
queue.on('progress', function(job, progress) {
const progresses = [];
queue.on('progress', (job, progress) => {
progresses.push(progress);
});
queue.add({ foo: 'bar' });
});
it('should process and fail', function(done) {
it('should process and fail', done => {
queue.process(__dirname + '/fixtures/fixture_processor_fail.js');
queue.on('failed', function(job, err) {
queue.on('failed', (job, err) => {
try {
expect(job.data).eql({ foo: 'bar' });
expect(job.failedReason).eql('Manually failed processor');
@@ -243,7 +242,7 @@ describe('sandboxed process', function() {
queue.add({ foo: 'bar' });
});
it('should error if processor file is missing', function(done) {
it('should error if processor file is missing', done => {
try {
queue.process(__dirname + '/fixtures/missing_processor.js');
done(new Error('did not throw error'));
@@ -252,10 +251,10 @@ describe('sandboxed process', function() {
}
});
it('should process and fail using callback', function(done) {
it('should process and fail using callback', done => {
queue.process(__dirname + '/fixtures/fixture_processor_callback_fail.js');
queue.on('failed', function(job, err) {
queue.on('failed', (job, err) => {
try {
expect(job.data).eql({ foo: 'bar' });
expect(job.failedReason).eql('Manually failed processor');
@@ -271,61 +270,61 @@ describe('sandboxed process', function() {
queue.add({ foo: 'bar' });
});
it('should fail if the process crashes', function() {
it('should fail if the process crashes', () => {
queue.process(__dirname + '/fixtures/fixture_processor_crash.js');
return queue
.add({})
.then(function(job) {
.then(job => {
return pReflect(Promise.resolve(job.finished()));
})
.then(function(inspection) {
.then(inspection => {
expect(inspection.isRejected).to.be.eql(true);
expect(inspection.reason.message).to.be.eql('boom!');
});
});
it('should fail if the process exits 0', function() {
it('should fail if the process exits 0', () => {
queue.process(__dirname + '/fixtures/fixture_processor_crash.js');
return queue
.add({ exitCode: 0 })
.then(function(job) {
.then(job => {
return pReflect(Promise.resolve(job.finished()));
})
.then(function(inspection) {
.then(inspection => {
expect(inspection.isRejected).to.be.eql(true);
expect(inspection.reason.message).to.be.eql('Unexpected exit code: 0');
});
});
it('should fail if the process exits non-0', function() {
it('should fail if the process exits non-0', () => {
queue.process(__dirname + '/fixtures/fixture_processor_crash.js');
return queue
.add({ exitCode: 1 })
.then(function(job) {
.then(job => {
return pReflect(Promise.resolve(job.finished()));
})
.then(function(inspection) {
.then(inspection => {
expect(inspection.isRejected).to.be.eql(true);
expect(inspection.reason.message).to.be.eql('Unexpected exit code: 1');
});
});
it('should remove exited process', function(done) {
it('should remove exited process', done => {
queue.process(__dirname + '/fixtures/fixture_processor_exit.js');
queue.on('completed', function() {
queue.on('completed', () => {
try {
expect(Object.keys(queue.childPool.retained)).to.have.lengthOf(0);
expect(queue.childPool.getAllFree()).to.have.lengthOf(1);
delay(500)
.then(function() {
.then(() => {
expect(Object.keys(queue.childPool.retained)).to.have.lengthOf(0);
expect(queue.childPool.getAllFree()).to.have.lengthOf(0);
})
.then(function() {
.then(() => {
done();
}, done);
} catch (err) {
+13 -14
View File
@@ -1,17 +1,16 @@
/*eslint-env node */
'use strict';
var expect = require('chai').expect;
var utils = require('./utils');
var redis = require('ioredis');
const expect = require('chai').expect;
const utils = require('./utils');
const redis = require('ioredis');
describe('workers', function() {
var queue;
var client;
describe('workers', () => {
let queue;
let client;
beforeEach(function() {
beforeEach(() => {
client = new redis();
return client.flushdb().then(function() {
return client.flushdb().then(() => {
queue = utils.buildQueue('test workers', {
settings: {
guardInterval: 300000,
@@ -22,16 +21,16 @@ describe('workers', function() {
});
});
afterEach(function() {
return queue.close().then(function() {
afterEach(() => {
return queue.close().then(() => {
return client.quit();
});
});
it('should get all workers for this queue', function() {
queue.process(function() {});
it('should get all workers for this queue', () => {
queue.process(() => {});
return queue.getWorkers().then(function(workers) {
return queue.getWorkers().then(workers => {
expect(workers).to.have.length(1);
});
});
+18 -19
View File
@@ -1,13 +1,12 @@
/*eslint-env node */
'use strict';
var Queue = require('../');
var STD_QUEUE_NAME = 'test queue';
var _ = require('lodash');
const Queue = require('../');
const STD_QUEUE_NAME = 'test queue';
const _ = require('lodash');
var queues = [];
let queues = [];
var originalSetTimeout = setTimeout;
const originalSetTimeout = setTimeout;
function simulateDisconnect(queue) {
queue.client.disconnect();
@@ -16,13 +15,13 @@ function simulateDisconnect(queue) {
function buildQueue(name, options) {
options = _.extend({ redis: { port: 6379, host: '127.0.0.1' } }, options);
var queue = new Queue(name || STD_QUEUE_NAME, options);
const queue = new Queue(name || STD_QUEUE_NAME, options);
queues.push(queue);
return queue;
}
function newQueue(name, opts) {
var queue = buildQueue(name, opts);
const queue = buildQueue(name, opts);
return queue.isReady();
}
@@ -32,29 +31,29 @@ function cleanupQueue(queue) {
function cleanupQueues() {
return Promise.all(
queues.map(function(queue) {
var errHandler = function() {};
queues.map(queue => {
const errHandler = function() {};
queue.on('error', errHandler);
return queue.close().catch(errHandler);
})
).then(function() {
).then(() => {
queues = [];
});
}
function sleep(ms) {
return new Promise(function(resolve) {
originalSetTimeout(function() {
return new Promise(resolve => {
originalSetTimeout(() => {
resolve();
}, ms);
});
}
module.exports = {
simulateDisconnect: simulateDisconnect,
buildQueue: buildQueue,
cleanupQueue: cleanupQueue,
newQueue: newQueue,
cleanupQueues: cleanupQueues,
sleep: sleep
simulateDisconnect,
buildQueue,
cleanupQueue,
newQueue,
cleanupQueues,
sleep
};