// 远程执行系统 - 实现类 import type { RemoteExecutionSystem, Device, Task, TaskStatus, StatusHandler, Result, DeviceStatus } from './types'; import { generateId } from '../../utils/id'; import { createLogger } from '../../utils/logger'; const log = createLogger('RemoteExecution'); export class RemoteExecutionEngine implements RemoteExecutionSystem { private devices: Map = new Map(); private tasks: Map = new Map(); private subscriptions: Map = new Map(); private runningCount = 0; private maxConcurrent: number; private pendingQueue: Task[] = []; constructor(maxConcurrent: number = 5) { this.maxConcurrent = maxConcurrent; } async registerDevice(device: Device): Promise { this.devices.set(device.id, device); log.info(`Device registered: ${device.id} (${device.platform})`); } async heartbeat(deviceId: string): Promise { const device = this.devices.get(deviceId); if (!device) { throw new Error(`Device not found: ${deviceId}`); } device.lastHeartbeat = new Date(); return device.status; } async submitTask(task: Task): Promise { task.id = task.id || generateId('task'); task.status = 'pending'; task.createdAt = new Date(); this.tasks.set(task.id, task); log.info(`Task submitted: ${task.id} (priority: ${task.priority})`); if (this.runningCount < this.maxConcurrent) { this.executeTask(task).catch(err => log.error(`Task execution error: ${err.message}`)); } else { this.pendingQueue.push(task); log.debug(`Task queued (${this.pendingQueue.length} pending)`); } return task.id; } async cancelTask(taskId: string): Promise { const task = this.tasks.get(taskId); if (!task) throw new Error(`Task not found: ${taskId}`); task.status = 'cancelled'; this.notifySubscribers(taskId, 'cancelled'); log.info(`Task cancelled: ${taskId}`); } async getStatus(taskId: string): Promise { const task = this.tasks.get(taskId); if (!task) throw new Error(`Task not found: ${taskId}`); return task.status; } getTask(taskId: string): Task | undefined { return this.tasks.get(taskId); } getDevice(deviceId: string): Device | undefined { return this.devices.get(deviceId); } listDevices(): Device[] { return Array.from(this.devices.values()); } listTasks(filter?: { status?: TaskStatus; userId?: string }): Task[] { let tasks = Array.from(this.tasks.values()); if (filter?.status) tasks = tasks.filter(t => t.status === filter.status); if (filter?.userId) tasks = tasks.filter(t => t.userId === filter.userId); return tasks.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime()); } subscribe(taskId: string, handler: StatusHandler): void { if (!this.subscriptions.has(taskId)) { this.subscriptions.set(taskId, []); } this.subscriptions.get(taskId)!.push(handler); } async pushResult(taskId: string, result: Result): Promise { const task = this.tasks.get(taskId); if (!task) throw new Error(`Task not found: ${taskId}`); task.result = result; task.status = result.success ? 'completed' : 'failed'; task.completedAt = new Date(); this.notifySubscribers(taskId, task.status); } getStats(): { total: number; running: number; pending: number; completed: number; failed: number } { const tasks = Array.from(this.tasks.values()); return { total: tasks.length, running: tasks.filter(t => t.status === 'running').length, pending: tasks.filter(t => t.status === 'pending').length, completed: tasks.filter(t => t.status === 'completed').length, failed: tasks.filter(t => t.status === 'failed').length, }; } private async executeTask(task: Task): Promise { this.runningCount++; try { task.status = 'running'; task.startedAt = new Date(); this.notifySubscribers(task.id, 'running'); log.info(`Executing task: ${task.id}`); // TODO: 集成 OpenClaw SDK 实际执行 await new Promise(resolve => setTimeout(resolve, 1000)); await this.pushResult(task.id, { taskId: task.id, success: true, data: { message: 'Task completed successfully' } }); } catch (error: any) { await this.pushResult(task.id, { taskId: task.id, success: false, error: error.message }); } finally { this.runningCount--; this.processNextInQueue(); } } private processNextInQueue(): void { if (this.pendingQueue.length > 0 && this.runningCount < this.maxConcurrent) { // 按优先级排序 this.pendingQueue.sort((a, b) => { const priority: Record = { high: 0, normal: 1, low: 2 }; return (priority[a.priority] ?? 1) - (priority[b.priority] ?? 1); }); const next = this.pendingQueue.shift()!; this.executeTask(next).catch(err => log.error(`Queued task error: ${err.message}`)); } } private notifySubscribers(taskId: string, status: TaskStatus, progress?: number): void { const handlers = this.subscriptions.get(taskId); if (handlers) { handlers.forEach(handler => handler(status, progress)); } } }