@eggjs/schedule
Version:
schedule plugin for egg, support corn job.
101 lines (87 loc) • 2.75 kB
text/typescript
import { debuglog } from 'node:util';
import type { Agent, EggLogger } from 'egg';
import { loadSchedule } from './load_schedule.js';
import type { EggScheduleItem, EggScheduleJobInfo } from './types.js';
import type { BaseStrategy } from './strategy/base.js';
const debug = debuglog('@eggjs/schedule/lib/schedule');
export class Schedule {
closed = false;
#agent: Agent;
#logger: EggLogger;
#strategyClassMap = new Map<string, typeof BaseStrategy>();
#strategyInstanceMap = new Map<string, BaseStrategy>();
constructor(agent: Agent) {
this.#agent = agent;
this.#logger = agent.getLogger('scheduleLogger');
}
/**
* register a custom Schedule Strategy
* @param {String} type - strategy type
* @param {Strategy} clz - Strategy class
*/
use(type: string, clz: typeof BaseStrategy) {
this.#strategyClassMap.set(type, clz);
debug('use type: %o', type);
}
/**
* load all schedule jobs, then initialize and register speical strategy
*/
async init() {
const scheduleItems = await loadSchedule(this.#agent);
for (const scheduleItem of Object.values(scheduleItems)) {
this.registerSchedule(scheduleItem);
}
}
registerSchedule(scheduleItem: EggScheduleItem) {
const { key, schedule } = scheduleItem;
const type = schedule.type;
if (schedule.disable) {
return;
}
// find Strategy by type
const Strategy = this.#strategyClassMap.get(type!);
if (!Strategy) {
const err = new Error(`schedule type [${type}] is not defined`);
err.name = 'EggScheduleError';
throw err;
}
// Initialize strategy and register
const instance = new Strategy(schedule, this.#agent, key);
this.#strategyInstanceMap.set(key, instance);
debug('registerSchedule type: %o, config: %o, key: %o', type, schedule, key);
}
unregisterSchedule(key: string) {
debug('unregisterSchedule key: %o', key);
return this.#strategyInstanceMap.delete(key);
}
/**
* job finish event handler
*
* @param {Object} info - { id, key, success, message, workerId }
*/
onJobFinish(info: EggScheduleJobInfo) {
this.#logger.debug(`[Job#${info.id}] ${info.key} finish event received by agent from worker#${info.workerId}`);
const instance = this.#strategyInstanceMap.get(info.key);
/* istanbul ignore else */
if (instance) {
instance.onJobFinish(info);
}
}
/**
* start schedule
*/
start() {
debug('start');
this.closed = false;
for (const instance of this.#strategyInstanceMap.values()) {
instance.start();
}
}
close() {
this.closed = true;
for (const instance of this.#strategyInstanceMap.values()) {
instance.close();
}
debug('close');
}
}