import { Server } from "socket.io"; import { l33tSerializer } from "./misc"; import { L33tTask } from "l33t-lib"; import { L33tGeometryUtil } from "./L33tGeometryUtil"; import { L33tMemDB } from "l33t-lib"; import { promises as fs } from 'fs'; import { WORKING_DIR } from "~/server/server"; import path from "path"; export class L33tTaskManager { constructor(private io: Server, private memoryDB: L33tMemDB) {} async start(key: string) { const task = this.memoryDB.tasks[key]; if (!task?.path) return; try { const fullPath = path.isAbsolute(task.path) ? task.path : path.join(WORKING_DIR, task.path); const sourceContent = await fs.readFile(fullPath, 'utf8'); this.memoryDB.tasks[key].fileContent = sourceContent; console.log("SOURCE content loaded for", fullPath); var mod = await import(`file://${fullPath}?update=${Date.now()}`); if (mod?.init) { console.log("Init ", mod); await mod.init(this.memoryDB); } var x = async () => { if (task.path && mod?.run) { try { let r = await mod.run(this.memoryDB); this.memoryDB.tasks[key].timedPrevious = task.timedLast; this.memoryDB.tasks[key].timedLast = Date.now(); this.memoryDB.tasks[key].lastResult = r; this.io.emit("l33t_task_exec", l33tSerializer({ key, task: this.memoryDB.tasks[key] })); } catch(e: any) { this.memoryDB.tasks[key].error = e.toString(); this.io.emit("l33t_task_exec", l33tSerializer({ key, task: this.memoryDB.tasks[key] })); console.log("error ", e); } } task._nodeinterval = setTimeout( () => x(), task.scheduledInterval); } x(); this.memoryDB.tasks[key].isStarted = true; } catch (error: any) { this.memoryDB.tasks[key].error = error.toString(); console.error('--------------'); console.error(`Error executing task ${key}:`, error.toString()); console.error('--------------'); this.io.emit("l33t_task_exec", l33tSerializer({ key, task: this.memoryDB.tasks[key] })); } } startAll() { Object.keys(this.memoryDB.tasks).forEach(async (key) => { await this.start(key); }); } stop(key: string) { const task = this.memoryDB.tasks[key]; if (task?._nodeinterval) { clearInterval(task._nodeinterval); task._nodeinterval = null; task.isStarted = false; } } stopAll() { Object.keys(this.memoryDB.tasks).forEach((key) => { this.stop(key); }); } async save(id: string, source: string) { const task = this.memoryDB.tasks[id]; if (!task) { throw new Error(id + " task not found"); } if (!task.path) { throw new Error(id + " task path is null or undefined"); } const fullPath = task.path.startsWith(WORKING_DIR) ? task.path : path.join(WORKING_DIR, task.path); if (!fullPath || !source) { throw new Error(id + " task not found or source empty"); } await fs.writeFile(fullPath, source, 'utf8'); this.memoryDB.tasks[id].fileContent = source; console.log("wwrite") this.stop(id); console.log("wwrite stop") await this.start(id); console.log("wwrite start") } async applyConfig(configfile: Record) { this.stopAll(); this.memoryDB.tasks = configfile; return true; } }