1
0
silverbullet/plugbox/feature/node_cron.ts

71 lines
1.8 KiB
TypeScript
Raw Normal View History

2022-03-23 14:41:12 +00:00
import { Feature, Manifest } from "../types";
import cron, { ScheduledTask } from "node-cron";
import { safeRun } from "../util";
import { System } from "../system";
export type CronHook = {
crons?: CronDef[];
};
export type CronDef = {
cron: string;
handler: string; // function name
};
export class NodeCronFeature implements Feature<CronHook> {
apply(system: System<CronHook>): void {
let tasks: ScheduledTask[] = [];
system.on({
plugLoaded: (name, plug) => {
reloadCrons();
},
plugUnloaded(name, plug) {
reloadCrons();
},
});
reloadCrons();
function reloadCrons() {
// ts-ignore
tasks.forEach((task) => task.stop());
tasks = [];
for (let plug of system.loadedPlugs.values()) {
const crons = plug.manifest?.hooks?.crons;
if (crons) {
for (let cronDef of crons) {
tasks.push(
cron.schedule(cronDef.cron, () => {
console.log("Now acting on cron", cronDef.cron);
safeRun(async () => {
try {
await plug.invoke(cronDef.handler, []);
} catch (e: any) {
console.error("Execution of cron function failed", e);
}
});
})
);
}
}
}
}
}
validateManifest(manifest: Manifest<CronHook>): string[] {
const crons = manifest.hooks.crons;
let errors = [];
if (crons) {
for (let cronDef of crons) {
if (!cron.validate(cronDef.cron)) {
errors.push(`Invalid cron expression ${cronDef.cron}`);
}
if (!manifest.functions[cronDef.handler]) {
errors.push(`Cron handler function ${cronDef.handler} not found`);
}
}
}
return errors;
}
}