From a8cb8a21ea52437ac507097994ef0fde058c5433 Mon Sep 17 00:00:00 2001 From: Rogger Valverde Date: Tue, 10 Sep 2024 06:36:10 -0600 Subject: [PATCH] fix(pattern): do not save offset when immediately is provided (#2756) --- src/classes/repeat.ts | 8 +++-- tests/test_repeat.ts | 72 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/src/classes/repeat.ts b/src/classes/repeat.ts index 1f1c2fe880..7ebae338d0 100644 --- a/src/classes/repeat.ts +++ b/src/classes/repeat.ts @@ -65,7 +65,7 @@ export class Repeat extends QueueBase { const hasImmediately = Boolean( (every || pattern) && repeatOpts.immediately, ); - const offset = hasImmediately ? now - nextMillis : undefined; + const offset = (hasImmediately && every) ? now - nextMillis : undefined; if (nextMillis) { // We store the undecorated opts.jobId into the repeat options if (!prevMillis && opts.jobId) { @@ -340,7 +340,11 @@ export const getNextMillis = ( }); try { - return interval.next().getTime(); + if(opts.immediately){ + return new Date().getTime(); + } else { + return interval.next().getTime(); + } } catch (e) { // Ignore error } diff --git a/tests/test_repeat.ts b/tests/test_repeat.ts index d6120dc7d2..b72a224159 100644 --- a/tests/test_repeat.ts +++ b/tests/test_repeat.ts @@ -843,7 +843,7 @@ describe('repeat', function () { delayStub.restore(); }); - it('should repeat once a day for 5 days and start immediately', async function () { + it('should repeat once a day for 5 days and start immediately using endDate', async function () { this.timeout(8000); const date = new Date('2017-05-05 01:01:00'); @@ -909,6 +909,76 @@ describe('repeat', function () { delayStub.restore(); }); + it('should repeat once a day for 5 days and start immediately', async function () { + this.timeout(8000); + + const date = new Date('2017-05-05 01:01:00'); + this.clock.setSystemTime(date); + + const nextTick = ONE_DAY + 10 * ONE_SECOND; + const delay = 5 * ONE_SECOND + 500; + + let counter = 0; + const worker = new Worker( + queueName, + async () => { + if(counter === 0){ + this.clock.tick(6 * ONE_HOUR); + + }else { + this.clock.tick(nextTick); + } + }, + { + autorun: false, + connection, + prefix, + skipStalledCheck: true, + skipLockRenewal: true, + }, + ); + const delayStub = sinon.stub(worker, 'delay').callsFake(async () => { + console.log('delay'); + }); + + let prev: Job; + const completing = new Promise((resolve, reject) => { + worker.on('completed', async job => { + if (counter === 1) { + expect(prev.timestamp).to.be.lt(job.timestamp); + expect(job.timestamp - prev.timestamp).to.be.gte(delay); + } else if (prev) { + expect(prev.timestamp).to.be.lt(job.timestamp); + expect(job.timestamp - prev.timestamp).to.be.gte(ONE_DAY); + } + prev = job; + + counter++; + if (counter == 5) { + resolve(); + } + }); + }); + + await queue.add( + 'repeat', + { foo: 'bar' }, + { + repeat: { + pattern: '0 0 7 * * *', + immediately: true, + }, + }, + ); + this.clock.tick(delay); + + worker.run(); + + await completing; + await worker.close(); + delayStub.restore(); + }); + it('should repeat once a day for 5 days', async function () { this.timeout(8000);