Skip to content

Commit

Permalink
fix(Schedule Trigger Node): Fixes inconsitent behavior with cron and …
Browse files Browse the repository at this point in the history
…weekly intervals (#4558)

* 🐛 Fixes weekly schedule trigger and inconsitent behavior from Cron

* 🐛  Explicitly check if number of items is undefined

* 🐛 Add flag for first time execution

* Fix merge issues

* 🎨 Decomplexise logic for week interval

* fix: account for periods longer than minimum interval and first executions

Co-authored-by: Omar Ajoue <krynble@gmail.com>
  • Loading branch information
agobrech and krynble authored Nov 21, 2022
1 parent a6df51b commit 2fb8ed8
Showing 1 changed file with 41 additions and 5 deletions.
46 changes: 41 additions & 5 deletions packages/nodes-base/nodes/Schedule/ScheduleTrigger.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,13 @@ export class ScheduleTrigger implements INodeType {
const timezone = this.getTimezone();
const cronJobs: CronJob[] = [];
const intervalArr: NodeJS.Timeout[] = [];
const executeTrigger = () => {
const staticData = this.getWorkflowStaticData('node') as {
recurrencyRules: number[];
};
if (!staticData.recurrencyRules) {
staticData.recurrencyRules = [];
}
const executeTrigger = (recurrencyRuleIndex?: number, weeksInterval?: number) => {
const resultData = {
timestamp: moment.tz(timezone).toISOString(true),
'Readable date': moment.tz(timezone).format('MMMM Do YYYY, h:mm:ss a'),
Expand All @@ -429,8 +435,27 @@ export class ScheduleTrigger implements INodeType {
Second: moment.tz(timezone).format('ss'),
Timezone: moment.tz(timezone).format('z Z'),
};
this.emit([this.helpers.returnJsonArray([resultData])]);
const lastExecutionWeekNumber =
recurrencyRuleIndex !== undefined
? staticData.recurrencyRules[recurrencyRuleIndex]
: undefined;

// Checks if have the right week interval, handles new years as well
if (weeksInterval && recurrencyRuleIndex !== undefined) {
if (
lastExecutionWeekNumber === undefined || // First time executing this rule
moment.tz(timezone).week() >= weeksInterval + lastExecutionWeekNumber || // not first time, but minimum interval has passed
moment.tz(timezone).week() + 52 >= weeksInterval + lastExecutionWeekNumber // not first time, correct interval but year has passed
) {
staticData.recurrencyRules[recurrencyRuleIndex] = moment.tz(timezone).week();
this.emit([this.helpers.returnJsonArray([resultData])]);
}
// There is no else block here since we don't want to emit anything now
} else {
this.emit([this.helpers.returnJsonArray([resultData])]);
}
};

for (let i = 0; i < interval.length; i++) {
let intervalValue = 1000;
if (interval[i].field === 'cronExpression') {
Expand Down Expand Up @@ -484,10 +509,21 @@ export class ScheduleTrigger implements INodeType {
const week = interval[i].weeksInterval as number;
const days = interval[i].triggerAtDay as IDataObject[];
const day = days.length === 0 ? '*' : (days.join(',') as string);
const cronTimes: string[] = [minute, hour, `*/${week * 7}`, '*', day];
const cronTimes: string[] = [minute, hour, '*', '*', day];
const cronExpression = cronTimes.join(' ');
const cronJob = new CronJob(cronExpression, executeTrigger, undefined, true, timezone);
cronJobs.push(cronJob);
if (week === 1) {
const cronJob = new CronJob(cronExpression, executeTrigger, undefined, true, timezone);
cronJobs.push(cronJob);
} else {
const cronJob = new CronJob(
cronExpression,
() => executeTrigger(i, week),
undefined,
true,
timezone,
);
cronJobs.push(cronJob);
}
}

if (interval[i].field === 'months') {
Expand Down

0 comments on commit 2fb8ed8

Please sign in to comment.