UNPKG

@eggjs/schedule

Version:

schedule plugin for egg, support corn job.

75 lines (68 loc) 2.97 kB
import path from 'node:path'; import assert from 'node:assert'; import { stringify } from 'node:querystring'; import { isClass, isFunction, isGeneratorFunction } from 'is-type-of'; import { importResolve } from '@eggjs/utils'; import type { EggApplicationCore, EggContext } from 'egg'; import type { EggScheduleConfig, EggScheduleTask, EggScheduleItem } from './types.js'; function getScheduleLoader(app: EggApplicationCore) { return class ScheduleLoader extends app.loader.FileLoader { async load() { const target = this.options.target as Record<string, EggScheduleItem>; const items = await this.parse(); for (const item of items) { const schedule = item.exports as { schedule: EggScheduleConfig, task: EggScheduleTask }; const fullpath = item.fullpath; const scheduleConfig = schedule.schedule; assert(scheduleConfig, `schedule(${fullpath}): must have "schedule" and "task" properties`); assert(isClass(schedule) || isFunction(schedule.task), `schedule(${fullpath}: \`schedule.task\` should be function or \`schedule\` should be class`); let task: EggScheduleTask; if (isClass(schedule)) { assert(!isGeneratorFunction(schedule.prototype.subscribe), `schedule(${fullpath}): "schedule" generator function is not support, should use async function instead`); task = async (ctx: EggContext, ...args: any[]) => { const instance = new schedule(ctx); // s.subscribe = app.toAsyncFunction(s.subscribe); return instance.subscribe(...args); }; } else { assert(!isGeneratorFunction(schedule.task), `schedule(${fullpath}): "task" generator function is not support, should use async function instead`); task = schedule.task; // task = app.toAsyncFunction(schedule.task); } const env = app.config.env; const envList = schedule.schedule.env; if (Array.isArray(envList) && !envList.includes(env)) { app.coreLogger.info(`[@eggjs/schedule]: ignore schedule ${fullpath} due to \`schedule.env\` not match`); continue; } // handle symlink case const realFullpath = importResolve(fullpath); target[realFullpath] = { schedule: scheduleConfig, scheduleQueryString: stringify(scheduleConfig as any), task, key: realFullpath, }; } return target; } }; } export async function loadSchedule(app: EggApplicationCore) { const dirs = [ ...app.loader.getLoadUnits().map(unit => path.join(unit.path, 'app/schedule')), ...app.config.schedule.directory, ]; const Loader = getScheduleLoader(app); const schedules = {} as Record<string, EggScheduleItem>; await new Loader({ directory: dirs, target: schedules, inject: app, }).load(); Reflect.set(app, 'schedules', schedules); return schedules; }