apssouza22/webgpu-cluster
0
1import {DetectTaskHandler} from './tasks/DetectTaskHandler';2import {DescribeTaskHandler} from './tasks/DescribeTaskHandler';3import {AbstractModelTaskHandler} from './tasks/AbstractModelTaskHandler';4import type {5 ClusterTaskHandlerOptions,6 ClusterTaskHostContext,7 ClusterTaskKind,8 HostTaskMessage,9} from './tasks/types';10 11export type {ClusterTaskKind, HostTaskMessage, ClusterTaskHandlerOptions} from './tasks/types';12 13export class ClusterTaskHandler {14 private readonly taskQueue: HostTaskMessage[] = [];15 private processing = false;16 private readonly host: ClusterTaskHostContext;17 private readonly handlers: Map<ClusterTaskKind, AbstractModelTaskHandler>;18 19 constructor(options: ClusterTaskHandlerOptions) {20 this.host = {21 apiBase: options.apiBase,22 getSelectedModelId: options.getSelectedModelId,23 setStatus: options.setStatus,24 };25 26 this.handlers = new Map<ClusterTaskKind, AbstractModelTaskHandler>([27 ['detect', new DetectTaskHandler(this.host, options.getDetector)],28 ['describe', new DescribeTaskHandler(this.host, options.getDescriber)],29 ]);30 }31 32 enqueueTask(task: HostTaskMessage): void {33 this.taskQueue.push(task);34 void this.drainTaskQueue();35 }36 37 parseIncomingTask(38 raw: HostTaskMessage & {kind?: ClusterTaskKind},39 defaultKind: ClusterTaskKind,40 ): HostTaskMessage {41 return {42 ...raw,43 kind: raw.kind ?? defaultKind,44 };45 }46 47 private async drainTaskQueue(): Promise<void> {48 if (this.processing || this.taskQueue.length === 0) {49 return;50 }51 52 const task = this.taskQueue.shift();53 if (task) {54 await this.processTask(task);55 }56 }57 58 private async processTask(task: HostTaskMessage): Promise<void> {59 const handler = this.handlers.get(task.kind);60 if (!handler) {61 throw new Error(`No handler for task kind '${task.kind}'`);62 }63 64 this.processing = true;65 this.host.setStatus(`Processing task ${task.id.slice(0, 8)}…`);66 67 try {68 await handler.process(task);69 this.host.setStatus(`Task ${task.id.slice(0, 8)} complete. Waiting for requests…`);70 } catch (error) {71 const message = error instanceof Error ? error.message : String(error);72 this.host.setStatus(`Task failed: ${message}`);73 } finally {74 this.processing = false;75 void this.drainTaskQueue();76 }77 }78}79 