mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-03 22:19:42 +02:00
perf: optimize for long-running Claude sessions
Critical fixes (unbounded growth): - Add 64KB line buffer limit with 100ms periodic flush in session.ts - Add task tracker cleanup (max 100 completed tasks) - Add scheduled runs auto-cleanup after 1 hour - Fix session leaks in scheduled run iterations High priority (performance): - Add SSE event batching (50ms output, 100ms task updates) - Parallelize screen stats with Promise.all() - Add 1MB buffer limit to respawn controller Medium priority (frontend): - Make xterm scrollback configurable (default 5000) - Debounce renderSessionTabs() at 100ms New feature: - Add CPU and memory usage display in frontend header - New /api/system/stats endpoint Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
import { EventEmitter } from 'node:events';
|
||||
|
||||
// Maximum number of completed tasks to keep in memory
|
||||
const MAX_COMPLETED_TASKS = 100;
|
||||
|
||||
/**
|
||||
* Represents a background task spawned by Claude Code
|
||||
*/
|
||||
@@ -159,12 +162,54 @@ export class TaskTracker extends EventEmitter {
|
||||
} else {
|
||||
this.emit('taskCompleted', task);
|
||||
}
|
||||
|
||||
// Clean up old completed tasks to prevent unbounded growth
|
||||
this.cleanupCompletedTasks();
|
||||
}
|
||||
|
||||
// Clean up pending
|
||||
this.pendingToolUses.delete(toolUseId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove old completed/failed tasks when exceeding the limit
|
||||
* Keeps running tasks and the most recent completed tasks
|
||||
*/
|
||||
private cleanupCompletedTasks(): void {
|
||||
const completedTasks: BackgroundTask[] = [];
|
||||
|
||||
// Collect all completed/failed tasks
|
||||
for (const task of this.tasks.values()) {
|
||||
if (task.status === 'completed' || task.status === 'failed') {
|
||||
completedTasks.push(task);
|
||||
}
|
||||
}
|
||||
|
||||
// If under limit, no cleanup needed
|
||||
if (completedTasks.length <= MAX_COMPLETED_TASKS) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Sort by end time (oldest first)
|
||||
completedTasks.sort((a, b) => (a.endTime || 0) - (b.endTime || 0));
|
||||
|
||||
// Remove oldest tasks beyond the limit
|
||||
const toRemove = completedTasks.slice(0, completedTasks.length - MAX_COMPLETED_TASKS);
|
||||
for (const task of toRemove) {
|
||||
// Remove from parent's children list if applicable
|
||||
if (task.parentId) {
|
||||
const parent = this.tasks.get(task.parentId);
|
||||
if (parent) {
|
||||
const childIndex = parent.children.indexOf(task.id);
|
||||
if (childIndex !== -1) {
|
||||
parent.children.splice(childIndex, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.tasks.delete(task.id);
|
||||
}
|
||||
}
|
||||
|
||||
private createTaskFromTerminal(agentType: string, context: string): void {
|
||||
const taskId = `terminal-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
||||
const parentId = this.taskStack.length > 0 ? this.taskStack[this.taskStack.length - 1] : null;
|
||||
|
||||
Reference in New Issue
Block a user