diff --git a/REFERENCE.md b/REFERENCE.md index 4c418d3d2..88885762c 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -282,7 +282,8 @@ interface RepeatOpts { startDate?: Date | string | number; // Start date when the repeat job should start repeating (only with cron). endDate?: Date | string | number; // End date when the repeat job should stop repeating. limit?: number; // Number of times the job should repeat at max. - every?: number; // Repeat every millis (cron setting cannot be used together with this setting.) + every?: number; // Repeat every milliseconds within the nearest interval of length "every" (cron setting cannot be used together with this setting.) + exactRecurrence?: boolean; // repeat job every n milliseconds regardless the interval of every (only with every.) count?: number; // The start value for the repeat iteration count. } ``` diff --git a/lib/repeatable.js b/lib/repeatable.js index 9f1cb576b..c813c8b5d 100644 --- a/lib/repeatable.js +++ b/lib/repeatable.js @@ -192,7 +192,9 @@ module.exports = function(Queue) { } if (opts.every) { - return Math.floor(millis / opts.every) * opts.every + opts.every; + return opts.exactRecurrence + ? millis + opts.every + : Math.floor(millis / opts.every) * opts.every + opts.every; } const currentDate = diff --git a/test/test_repeat.js b/test/test_repeat.js index cf1996d32..e6a475379 100644 --- a/test/test_repeat.js +++ b/test/test_repeat.js @@ -745,4 +745,41 @@ describe('repeat', () => { } }); }); + + it('should repeat every 2 seconds', function(done) { + this.timeout(20000); + const _this = this; + const date = new Date('2017-02-07 9:24:00'); + this.clock.tick(date.getTime()); + const nextTick = 2 * ONE_SECOND + 500; + + queue + .add( + 'repeat', + { foo: 'bar' }, + { repeat: { every: 2000, exactRecurrence: true } } + ) + .then(() => { + _this.clock.tick(nextTick); + }); + + queue.process('repeat', () => { + // dummy + }); + + let prev; + let counter = 0; + queue.on('completed', job => { + _this.clock.tick(nextTick); + if (prev) { + expect(prev.timestamp).to.be.lt(job.timestamp); + expect(job.timestamp - prev.timestamp).to.be.gte(2000); + } + prev = job; + counter++; + if (counter == 20) { + done(); + } + }); + }); });