cc工作前备份
This commit is contained in:
@@ -8,63 +8,88 @@ import type {
|
||||
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<string, Device> = new Map();
|
||||
private tasks: Map<string, Task> = new Map();
|
||||
private subscriptions: Map<string, StatusHandler[]> = new Map();
|
||||
private taskQueue: Task[] = [];
|
||||
private runningCount = 0;
|
||||
private maxConcurrent: number;
|
||||
private pendingQueue: Task[] = [];
|
||||
|
||||
constructor(maxConcurrent: number = 5) {
|
||||
this.maxConcurrent = maxConcurrent;
|
||||
}
|
||||
|
||||
async registerDevice(device: Device): Promise<void> {
|
||||
this.devices.set(device.id, device);
|
||||
console.log([RemoteExecution] Device registered: ());
|
||||
log.info(`Device registered: ${device.id} (${device.platform})`);
|
||||
}
|
||||
|
||||
async heartbeat(deviceId: string): Promise<DeviceStatus> {
|
||||
const device = this.devices.get(deviceId);
|
||||
if (!device) {
|
||||
throw new Error(Device not found: );
|
||||
throw new Error(`Device not found: ${deviceId}`);
|
||||
}
|
||||
|
||||
device.lastHeartbeat = new Date();
|
||||
return device.status;
|
||||
}
|
||||
|
||||
async submitTask(task: Task): Promise<string> {
|
||||
task.id = task.id || this.generateId();
|
||||
task.id = task.id || generateId('task');
|
||||
task.status = 'pending';
|
||||
task.createdAt = new Date();
|
||||
|
||||
this.tasks.set(task.id, task);
|
||||
this.taskQueue.push(task);
|
||||
|
||||
console.log([RemoteExecution] Task submitted: );
|
||||
|
||||
// 立即执行(后续会改为队列处理)
|
||||
this.executeTask(task).catch(console.error);
|
||||
|
||||
|
||||
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<void> {
|
||||
const task = this.tasks.get(taskId);
|
||||
if (!task) {
|
||||
throw new Error(Task not found: );
|
||||
}
|
||||
|
||||
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<TaskStatus> {
|
||||
const task = this.tasks.get(taskId);
|
||||
if (!task) {
|
||||
throw new Error(Task not found: );
|
||||
}
|
||||
|
||||
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, []);
|
||||
@@ -74,41 +99,61 @@ export class RemoteExecutionEngine implements RemoteExecutionSystem {
|
||||
|
||||
async pushResult(taskId: string, result: Result): Promise<void> {
|
||||
const task = this.tasks.get(taskId);
|
||||
if (!task) {
|
||||
throw new Error(Task not found: );
|
||||
}
|
||||
|
||||
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<void> {
|
||||
this.runningCount++;
|
||||
try {
|
||||
task.status = 'running';
|
||||
task.startedAt = new Date();
|
||||
this.notifySubscribers(task.id, 'running');
|
||||
|
||||
// TODO: 实际执行逻辑(调用 OpenClaw SDK)
|
||||
console.log([RemoteExecution] Executing task: );
|
||||
|
||||
// 模拟执行
|
||||
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<string, number> = { 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}`));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,8 +163,4 @@ export class RemoteExecutionEngine implements RemoteExecutionSystem {
|
||||
handlers.forEach(handler => handler(status, progress));
|
||||
}
|
||||
}
|
||||
|
||||
private generateId(): string {
|
||||
return ask__;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user