Files
Jellystat/backend/classes/task-manager.js

100 lines
2.6 KiB
JavaScript

const { Worker } = require("worker_threads");
const TaskList = require("../global/task-list");
const { sendUpdate } = require("../ws");
const taskstate = require("../logging/taskstate");
const db = require("../db");
class TaskManager {
constructor() {
this.tasks = {};
this.taskList = TaskList;
this.emitTaskList();
}
addTask({ task, onComplete, onError, onExit }) {
if (this.tasks[task.name]) {
console.log(`Task ${task.name} already exists.`);
return false;
}
const worker = new Worker(task.path);
worker.on("message", (message) => {
if (message.type === "log") {
// Handle console.log messages
console.log(`[Worker Log]: ${message.message}`);
}
if (message.status === "complete" && onComplete) {
onComplete();
}
if (message.status === "error" && onError) {
onError(new Error(message.message));
}
delete this.tasks[task.name];
});
worker.on("error", (error) => {
if (onError) {
onError(error);
}
console.error(`Error from ${task.name}:`, error);
delete this.tasks[task.name];
});
worker.on("exit", async (code) => {
if (code !== 0) {
console.error(`Worker ${task.name} stopped with exit code ${code}`);
}
if (code !== 0 && onExit) {
onExit();
}
delete this.tasks[task.name];
try {
await db.query(
`UPDATE jf_logging SET "Result"='${taskstate.FAILED}' WHERE "Result"='${taskstate.RUNNING}' AND "Name"='${task.name}'`
);
} catch (error) {
console.log("Clear Running Tasks Error: " + error);
}
});
this.tasks[task.name] = { worker };
return true;
}
startTask(task, triggerType) {
const taskExists = this.tasks[task.name];
if (!taskExists) {
console.log(`Task ${task.name} does not exist.`);
return;
}
taskExists.worker.postMessage({ command: "start", triggertype: triggerType });
}
stopTask(task) {
const taskExists = this.tasks[task.name];
if (!taskExists) {
console.log(`Task ${task.name} does not exist.`);
return;
}
taskExists.worker.terminate();
delete this.tasks[task.name];
}
isTaskRunning(taskName) {
return !!this.tasks[taskName];
}
emitTaskList() {
let emitTasks = setInterval(async () => {
const taskList = Object.keys(this.taskList).map((key) => {
return { task: key, name: this.taskList[key].name, running: this.isTaskRunning(this.taskList[key].name) };
});
sendUpdate("task-list", taskList);
}, 1000);
}
}
module.exports = TaskManager;