@eggjs/schedule
Version:
schedule plugin for egg, support corn job.
92 lines • 7.23 kB
JavaScript
import assert from 'node:assert';
import cronParser from 'cron-parser';
import { ms } from 'humanize-ms';
import safeTimers from 'safe-timers';
import { logDate } from 'utility';
import { BaseStrategy } from './base.js';
export class TimerStrategy extends BaseStrategy {
cronInstance;
constructor(scheduleConfig, agent, key) {
super(scheduleConfig, agent, key);
const { interval, cron, cronOptions, immediate } = this.scheduleConfig;
assert(interval || cron || immediate, `[/schedule] ${this.key} \`schedule.interval\` or \`schedule.cron\` or \`schedule.immediate\` must be present`);
// init cron parser
if (cron) {
try {
this.cronInstance = cronParser.parseExpression(cron, cronOptions);
}
catch (err) {
throw new TypeError(`[/schedule] ${this.key} parse cron instruction(${cron}) error: ${err.message}`, { cause: err });
}
}
}
handler() {
throw new TypeError(`[/schedule] ${this.key} strategy should override \`handler()\` method`);
}
start() {
/* istanbul ignore next */
if (this.agent.schedule.closed)
return;
if (this.scheduleConfig.immediate) {
this.logger.info(`[Timer] ${this.key} next time will execute immediate`);
setImmediate(() => this.handler());
}
else {
this.#scheduleNext();
}
}
#scheduleNext() {
/* istanbul ignore next */
if (this.agent.schedule.closed)
return;
// get next tick
const nextTick = this.getNextTick();
if (nextTick) {
this.logger.info(`[Timer] ${this.key} next time will execute after ${nextTick}ms at ${logDate(new Date(Date.now() + nextTick))}`);
this.safeTimeout(() => this.handler(), nextTick);
}
else {
this.logger.info(`[Timer] ${this.key} reach endDate, will stop`);
}
}
onJobStart() {
// Next execution will trigger task at a fix rate, regardless of its execution time.
this.#scheduleNext();
}
/**
* calculate next tick
*
* @return {Number|undefined} time interval, if out of range then return `undefined`
*/
getNextTick() {
// interval-style
if (this.scheduleConfig.interval) {
return ms(this.scheduleConfig.interval);
}
// cron-style
if (this.cronInstance) {
// calculate next cron tick
const now = Date.now();
let nextTick;
// loop to find next feature time
do {
try {
const nextInterval = this.cronInstance.next();
nextTick = nextInterval.getTime();
}
catch (err) {
// Error: Out of the timespan range
this.logger.info(`[Timer] ${this.key} cron out of the timespan range, error: %s`, err);
return;
}
} while (now >= nextTick);
return nextTick - now;
}
// won\'t run here
}
safeTimeout(handler, delay, ...args) {
const fn = delay < safeTimers.maxInterval ? setTimeout : safeTimers.setTimeout;
return fn(handler, delay, ...args);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3N0cmF0ZWd5L3RpbWVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sTUFBTSxNQUFNLGFBQWEsQ0FBQztBQUVqQyxPQUFPLFVBQVUsTUFBTSxhQUFhLENBQUM7QUFDckMsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNqQyxPQUFPLFVBQVUsTUFBTSxhQUFhLENBQUM7QUFDckMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUdsQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRXpDLE1BQU0sT0FBZ0IsYUFBYyxTQUFRLFlBQVk7SUFDNUMsWUFBWSxDQUFrQjtJQUV4QyxZQUFZLGNBQWlDLEVBQUUsS0FBWSxFQUFFLEdBQVc7UUFDdEUsS0FBSyxDQUFDLGNBQWMsRUFBRSxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFFbEMsTUFBTSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUM7UUFDdkUsTUFBTSxDQUFDLFFBQVEsSUFBSSxJQUFJLElBQUksU0FBUyxFQUNsQyxxQkFBcUIsSUFBSSxDQUFDLEdBQUcsdUZBQXVGLENBQUMsQ0FBQztRQUV4SCxtQkFBbUI7UUFDbkIsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUNULElBQUksQ0FBQztnQkFDSCxJQUFJLENBQUMsWUFBWSxHQUFHLFVBQVUsQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1lBQ3BFLENBQUM7WUFBQyxPQUFPLEdBQVEsRUFBRSxDQUFDO2dCQUNsQixNQUFNLElBQUksU0FBUyxDQUNqQixxQkFBcUIsSUFBSSxDQUFDLEdBQUcsMkJBQTJCLElBQUksWUFBWSxHQUFHLENBQUMsT0FBTyxFQUFFLEVBQ3JGLEVBQUUs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