From 8e16bab213ff2366eb686b0bbbe8ab28509df90b Mon Sep 17 00:00:00 2001 From: Junyi Date: Tue, 5 Mar 2024 21:08:46 +0800 Subject: [PATCH] fix(plugin-workflow): fix schedule repeat logic (#3612) * fix(plugin-workflow): fix schedule repeat logic * fix(plugin-workflow): fix test case --- .../triggers/schedule/mode-static.test.ts | 94 +++++++++++++------ .../ScheduleTrigger/StaticScheduleTrigger.ts | 4 +- 2 files changed, 66 insertions(+), 32 deletions(-) diff --git a/packages/plugins/@nocobase/plugin-workflow/src/server/__tests__/triggers/schedule/mode-static.test.ts b/packages/plugins/@nocobase/plugin-workflow/src/server/__tests__/triggers/schedule/mode-static.test.ts index 0a573e88f..7f74f8cbd 100644 --- a/packages/plugins/@nocobase/plugin-workflow/src/server/__tests__/triggers/schedule/mode-static.test.ts +++ b/packages/plugins/@nocobase/plugin-workflow/src/server/__tests__/triggers/schedule/mode-static.test.ts @@ -119,7 +119,8 @@ describe('workflow > triggers > schedule > static mode', () => { }); it('start before now and repeat every 2 seconds after created and limit 1', async () => { - const start = await sleepToEvenSecond(); + await sleepToEvenSecond(); + const start = new Date(); start.setMilliseconds(0); const workflow = await WorkflowModel.create({ @@ -166,6 +167,68 @@ describe('workflow > triggers > schedule > static mode', () => { expect(date.getTime()).toBe(now.getTime()); }); + it('no repeat triggered then update to repeat', async () => { + const start = await sleepToEvenSecond(); + + const workflow = await WorkflowModel.create({ + enabled: true, + type: 'schedule', + config: { + mode: 0, + startsOn: start.toISOString(), + }, + }); + + await sleep(1000); + + const e1s = await workflow.getExecutions(); + expect(e1s.length).toBe(0); + + await workflow.update({ + config: { + ...workflow.config, + repeat: 1000, + }, + }); + + console.log(new Date().toISOString()); + + await sleep(3000); + + const e2s = await workflow.getExecutions(); + console.log(e2s); + expect(e2s.length).toBe(2); + }); + }); + + describe('status', () => { + it('should not trigger after turned off', async () => { + const start = await sleepToEvenSecond(); + const future = new Date(); + future.setSeconds(future.getSeconds() + 2); + + const workflow = await WorkflowModel.create({ + enabled: true, + type: 'schedule', + config: { + mode: 0, + startsOn: future.toISOString(), + repeat: 1000, + }, + }); + + await sleep(1000); + + await workflow.update({ enabled: false }); + + await sleep(3000); + + const executions = await workflow.getExecutions(); + expect(executions.length).toBe(0); + }); + }); + + describe('dispatch', () => { it('multiple workflows trigger at same time', async () => { const now = new Date(); const startsOn = now.toISOString(); @@ -216,36 +279,7 @@ describe('workflow > triggers > schedule > static mode', () => { d2.setMilliseconds(0); expect(d2.getTime()).toBe(now.getTime()); }); - }); - describe('status', () => { - it('should not trigger after turned off', async () => { - const start = await sleepToEvenSecond(); - const future = new Date(); - future.setSeconds(future.getSeconds() + 2); - - const workflow = await WorkflowModel.create({ - enabled: true, - type: 'schedule', - config: { - mode: 0, - startsOn: future.toISOString(), - repeat: 1000, - }, - }); - - await sleep(1000); - - await workflow.update({ enabled: false }); - - await sleep(3000); - - const executions = await workflow.getExecutions(); - expect(executions.length).toBe(0); - }); - }); - - describe('dispatch', () => { it('missed non-repeated scheduled time should not be triggered', async () => { await sleepToEvenSecond(); diff --git a/packages/plugins/@nocobase/plugin-workflow/src/server/triggers/ScheduleTrigger/StaticScheduleTrigger.ts b/packages/plugins/@nocobase/plugin-workflow/src/server/triggers/ScheduleTrigger/StaticScheduleTrigger.ts index fc1e622a0..13436660d 100644 --- a/packages/plugins/@nocobase/plugin-workflow/src/server/triggers/ScheduleTrigger/StaticScheduleTrigger.ts +++ b/packages/plugins/@nocobase/plugin-workflow/src/server/triggers/ScheduleTrigger/StaticScheduleTrigger.ts @@ -27,7 +27,6 @@ export default class StaticScheduleTrigger { inspect(workflows) { const now = new Date(); - now.setMilliseconds(0); workflows.forEach((workflow) => { const nextTime = this.getNextTime(workflow, now); @@ -65,7 +64,8 @@ export default class StaticScheduleTrigger { const next = interval.next(); return next.getTime(); } else if (typeof config.repeat === 'number') { - return timestamp + ((timestamp - startTime) % config.repeat); + const next = timestamp + config.repeat - ((timestamp - startTime) % config.repeat); + return next; } else { return null; }