actionhero
Version:
The reusable, scalable, and quick node.js API server for stateless and stateful applications
145 lines (144 loc) • 6.56 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TasksInitializer = void 0;
const path = require("path");
const node_resque_1 = require("node-resque");
const index_1 = require("../index");
const safeGlob_1 = require("../modules/utils/safeGlob");
const taskModule = index_1.task;
/**
* Tools for enqueuing and inspecting the task system (delayed jobs).
*/
class TasksInitializer extends index_1.Initializer {
constructor() {
super();
this.loadFile = async (fullFilePath, reload = false) => {
let task;
let collection = await Promise.resolve(`${fullFilePath}`).then(s => require(s));
for (const i in collection) {
const TaskClass = collection[i];
task = new TaskClass();
task.validate();
if (index_1.api.tasks.tasks[task.name] && !reload) {
(0, index_1.log)(`an existing task with the same name \`${task.name}\` will be overridden by the file ${fullFilePath}`, "crit");
}
index_1.api.tasks.tasks[task.name] = task;
index_1.api.tasks.jobs[task.name] = index_1.api.tasks.jobWrapper(task.name);
(0, index_1.log)(`task ${reload ? "(re)" : ""} loaded: ${task.name}, ${fullFilePath}`, "debug");
}
};
this.jobWrapper = (taskName) => {
const task = index_1.api.tasks.tasks[taskName];
const middleware = task.middleware || [];
const plugins = task.plugins || [];
const pluginOptions = task.pluginOptions || {};
if (task.frequency > 0) {
if (plugins.indexOf("JobLock") < 0) {
plugins.push("JobLock");
pluginOptions.JobLock = { reEnqueue: false };
}
if (plugins.indexOf("QueueLock") < 0) {
plugins.push("QueueLock");
}
if (plugins.indexOf("DelayQueueLock") < 0) {
plugins.push("DelayQueueLock");
}
}
// load middleware into plugins
const processMiddleware = (m) => {
if (index_1.api.tasks.middleware[m]) {
class NodeResquePlugin extends node_resque_1.Plugin {
constructor(...args) {
super(...args);
}
async beforeEnqueue() {
return index_1.api.tasks.middleware[m].preEnqueue
? index_1.api.tasks.middleware[m].preEnqueue.call(this)
: true;
}
async afterEnqueue() {
return index_1.api.tasks.middleware[m].postEnqueue
? index_1.api.tasks.middleware[m].postEnqueue.call(this)
: true;
}
async beforePerform() {
return index_1.api.tasks.middleware[m].preProcessor
? index_1.api.tasks.middleware[m].preProcessor.call(this)
: true;
}
async afterPerform() {
return index_1.api.tasks.middleware[m].postProcessor
? index_1.api.tasks.middleware[m].postProcessor.call(this)
: true;
}
}
//@ts-ignore
plugins.push(NodeResquePlugin);
}
};
index_1.api.tasks.globalMiddleware.forEach(processMiddleware);
middleware.forEach(processMiddleware);
return {
plugins,
pluginOptions,
perform: async function () {
const combinedArgs = [].concat(Array.prototype.slice.call(arguments));
combinedArgs.push(this);
let response = null;
try {
response = await task.run.apply(task, combinedArgs);
await taskModule.enqueueRecurrentTask(taskName);
}
catch (error) {
if (task.frequency > 0 && task.reEnqueuePeriodicTaskIfException) {
await taskModule.enqueueRecurrentTask(taskName);
}
throw error;
}
return response;
},
};
};
this.loadTasks = async (reload) => {
for (const p of index_1.config.general.paths.task) {
await Promise.all(index_1.utils
.ensureNoTsHeaderOrSpecFiles((0, safeGlob_1.safeGlobSync)(path.join(p, "**", "**/*(*.js|*.ts)")))
.map((f) => index_1.api.tasks.loadFile(f, reload)));
}
for (const plugin of Object.values(index_1.config.plugins)) {
if (plugin.tasks !== false) {
const pluginPath = path.normalize(plugin.path);
// old style at the root of the project
let files = (0, safeGlob_1.safeGlobSync)(path.join(pluginPath, "tasks", "**", "*.js"));
files = files.concat((0, safeGlob_1.safeGlobSync)(path.join(pluginPath, "dist", "tasks", "**", "*.js")));
index_1.utils.ensureNoTsHeaderOrSpecFiles(files).forEach((f) => {
index_1.api.tasks.loadFile(f, reload);
});
}
}
};
this.name = "tasks";
this.loadPriority = 699;
this.startPriority = 975;
}
async initialize() {
index_1.api.tasks = {
tasks: {},
jobs: {},
middleware: {},
globalMiddleware: [],
loadFile: this.loadFile,
jobWrapper: this.jobWrapper,
loadTasks: this.loadTasks,
};
await index_1.api.tasks.loadTasks(false);
// we want to start the queue now, so that it's available for other initializers and CLI commands
await index_1.api.resque.startQueue();
}
async start() {
if (index_1.config.tasks.scheduler === true) {
await taskModule.enqueueAllRecurrentTasks();
}
}
}
exports.TasksInitializer = TasksInitializer;