import type { Entity } from "@infinity-beyond/mod.ts";
const tasks: I_Task[] = []
let queue_is_running: boolean = false;
export const TaskQueue = {
Entities: new Map<string, typeof Entity | Entity>(),
add(socket: WebSocket, request: I_ProcessorRequest) {
tasks.push({
socket,
request,
has_run: false
});
if(!queue_is_running) TaskQueue.process_queue();
},
async process_queue() {
if(queue_is_running) return false;
queue_is_running = true;
while(tasks.length) {
await this.run_next_queue_item();
}
queue_is_running = false;
},
async run_next_queue_item(): Promise<boolean> {
if(!tasks.length) return false;
let task: I_Task | undefined;
while(!task || task.has_run) {
task = tasks.shift();
}
if(!task) return false;
task.has_run = true;
const entity = TaskQueue.Entities.get(task.request.entity_name);
if(!entity) return failResponse(task, `Could not find [${task.request.entity_name}]!`);
const method = (entity as any)[task.request.method] as VagueFunction;
if(!method) return failResponse(task, `Could not find [${task.request.entity_name}::${task.request.method}()]!`);
try {
const response = await method.apply(entity, task.request.args) as Record<string, any>;
return succeedResponse(task, response);
} catch(e: any) {
return failResponse(task, `An error ocurred when trying to execute [${task.request.entity_name}::${task.request.method}()]`, e);
}
}
}
const succeedResponse = (task: I_Task, data: Record<string, any>) => {
task.socket.send(JSON.stringify({
id: task.request.id,
success: true,
data
}));
return true;
}
const failResponse = (task: I_Task, message: string, error?: Error) => {
task.socket.send(JSON.stringify({
id: task.request.id,
success: false,
message,
error: error && { name: error.name, message: error.message, cause: error.cause }
}));
return false;
}