@webda/core
Version:
Expose API with Lambda
141 lines • 4.53 kB
JavaScript
import { createHash } from "crypto";
import { schedule } from "node-cron";
import { CancelablePromise } from "../index.js";
import { Service } from "./service.js";
/**
* Cron item
*/
export class CronDefinition {
/**
*
* @param cron
* @param args
* @param serviceName
* @param method
* @param description
*/
constructor(cron, args = [], serviceName = "", method = "", description = "") {
this.cron = cron;
this.serviceName = serviceName;
this.method = method;
this.description = description;
this.args = args;
}
toString() {
return `${this.cron}: ${this.serviceName}.${this.method}(${this.args.map(a => a.toString()).join(",")})${this.description !== "" ? ` # ${this.description}` : ""}`;
}
}
/**
* @WebdaModda
*/
class CronService extends Service {
constructor() {
super(...arguments);
this.crons = [];
this.crontabSchedule = schedule;
this._scanned = false;
}
static Annotation(cron, description = "", ...args) {
return (_target, property, descriptor) => {
descriptor.value.cron = descriptor.value.cron || [];
descriptor.value.cron.push(new CronDefinition(cron, args, "", property, description));
};
}
static getCronId(cron, name = "") {
let hash = createHash("sha256");
return hash
.update(JSON.stringify(cron) + name)
.digest("hex")
.substring(0, 8);
}
static loadAnnotations(services) {
let cronsResult = [];
for (let i in services) {
let props = Object.getOwnPropertyDescriptors(services[i].constructor.prototype);
for (let method in props) {
// @ts-ignore
let crons = props[method].value?.cron;
if (crons) {
crons.forEach(cron => {
cron.method = method;
cron.serviceName = i;
cronsResult.push(cron);
});
}
}
}
return cronsResult;
}
addAnnotations() {
if (this._scanned) {
return;
}
this._scanned = true;
this.crons.push(...CronService.loadAnnotations(this._webda.getServices()));
}
getCrontab() {
// Load all annotations
this.addAnnotations();
return this.crons;
}
work(annotations = "true") {
return this.run(annotations === "true");
}
run(annotations = true) {
this.log("INFO", "Running crontab with" + (annotations ? "" : "out"), "annotations");
// Load all annotations
if (annotations) {
this.addAnnotations();
}
this.enable = true;
// Run schedule
this.crons.forEach(i => {
if (i.cb) {
this.schedule(i.cron, i.cb);
}
else {
this.schedule(i.cron, () => {
this.getService(i.serviceName)[i.method](...i.args);
});
}
});
let msgs = [];
// Display before
this.crons.forEach(c => {
if (c.cb) {
msgs.push(`[NativeCode:${c.context || ""}]`);
}
else {
msgs.push(`${c.serviceName}.${c.method}(${c.args.length ? "..." + c.args : ""})`);
}
});
let cronPad = Math.max(...this.crons.map(c => c.cron.length));
let servicePad = Math.max(...msgs.map(c => c.length));
this.crons.forEach((c, i) => {
this.log("INFO", `${c.cron.padEnd(cronPad)} : ${msgs[i].padEnd(servicePad)}${c.description ? " # " + c.description : ""}`);
});
// Remove from memory
this.crons = [];
return new CancelablePromise();
}
schedule(cron, cb, description = "") {
if (this.enable) {
this.crontabSchedule(cron, cb);
}
else {
let context;
try {
throw new Error();
}
catch (err) {
// Based on stack trace (not super clean)
let info = err.stack.split("\n")[2].match(/\((.*)\)/);
context = info[1].replace(process.cwd() + "/", "");
}
this.crons.push({ cron, cb, description, context });
}
}
}
const Cron = CronService.Annotation;
export { Cron, CronService };
//# sourceMappingURL=cron.js.map