Add shiftCronExpression utils

This commit is contained in:
fdel-car 2023-01-20 15:06:21 +01:00
parent 5f86716429
commit 6fe16dca5c
2 changed files with 45 additions and 12 deletions

View File

@ -4,7 +4,7 @@ const { pick } = require('lodash/fp');
const { readLicense, verifyLicense, fetchLicense, LicenseCheckError } = require('./license');
const { eeStoreModel } = require('./ee-store');
const { getRecurringCronExpression } = require('../lib/utils/cron');
const { shiftCronExpression } = require('../lib/utils/cron');
const ONE_MINUTE = 1000 * 60;
const DEFAULT_FEATURES = {
@ -142,7 +142,7 @@ const checkLicense = async ({ strapi }) => {
if (!shouldStayOffline) {
await onlineUpdate({ strapi });
strapi.cron.add({ [getRecurringCronExpression()]: onlineUpdate });
strapi.cron.add({ [shiftCronExpression('0 0 */12 * * *')]: onlineUpdate });
} else {
if (!ee.licenseInfo.expireAt) {
return disable('Your license does not have offline support.');

View File

@ -1,17 +1,50 @@
'use strict';
const shiftHours = (date, step) => {
const frequency = 24 / step;
const list = Array.from({ length: frequency }, (_, index) => index * step);
const hour = date.getHours();
return list.map((value) => (value + hour) % 24).sort((a, b) => a - b);
const { isEmpty, negate } = require('lodash/fp');
const integerRegex = /^\d+$/;
const stepRegex = /^\*\/\d+$/;
const components = [
{ limit: 60, zeroBasedIndices: true, functionName: 'getSeconds' },
{ limit: 60, zeroBasedIndices: true, functionName: 'getMinutes' },
{ limit: 24, zeroBasedIndices: true, functionName: 'getHours' },
{ limit: 31, zeroBasedIndices: false, functionName: 'getDate' },
{ limit: 12, zeroBasedIndices: false, functionName: 'getMonth' },
{ limit: 7, zeroBasedIndices: true, functionName: 'getDay' },
];
const shift = (component, index, date) => {
if (component === '*') {
return '*';
}
const { limit, zeroBasedIndices, functionName } = components[index];
const offset = +!zeroBasedIndices;
const currentValue = date[functionName]();
if (integerRegex.test(component)) {
return ((Number.parseInt(component, 10) + currentValue) % limit) + offset;
}
if (stepRegex.test(component)) {
const [, step] = component.split('/');
const frequency = Math.floor(limit / step);
const list = Array.from({ length: frequency }, (_, index) => index * step);
return list.map((value) => ((value + currentValue) % limit) + offset).sort((a, b) => a - b);
}
// Unsupported syntax, fallback to '*'
return '*';
};
// TODO: This should be transformed into a cron expression shifter that could be reused in other places
// For now it's tailored to the license check cron, scheduled every 12h
const getRecurringCronExpression = (date = new Date()) =>
`${date.getMinutes()} ${shiftHours(date, 12)} * * *`;
const shiftCronExpression = (rule, date = new Date()) => {
const components = rule.trim().split(' ').filter(negate(isEmpty));
const secondsIncluded = components.length === 6;
return components
.map((component, index) => shift(component, secondsIncluded ? index : index + 1, date))
.join(' ');
};
module.exports = {
getRecurringCronExpression,
shiftCronExpression,
};