@claude-flow/cli 3.0.0-alpha.7 → 3.0.0-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agentic-flow/intelligence.json +4 -4
- package/.claude-flow/daemon-state.json +23 -23
- package/.claude-flow/metrics/codebase-map.json +2 -2
- package/.claude-flow/metrics/consolidation.json +1 -1
- package/.claude-flow/metrics/performance.json +12 -84
- package/.claude-flow/metrics/security-audit.json +1 -1
- package/.claude-flow/metrics/task-metrics.json +3 -3
- package/.claude-flow/metrics/test-gaps.json +1 -1
- package/agents/architect.yaml +1 -1
- package/agents/coder.yaml +1 -1
- package/agents/reviewer.yaml +1 -1
- package/agents/security-architect.yaml +1 -1
- package/agents/tester.yaml +1 -1
- package/dist/src/services/worker-daemon.d.ts +29 -2
- package/dist/src/services/worker-daemon.d.ts.map +1 -1
- package/dist/src/services/worker-daemon.js +123 -20
- package/dist/src/services/worker-daemon.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/services/worker-daemon.ts +153 -21
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"patterns": {
|
|
3
3
|
"command:": {
|
|
4
|
-
"success": 0.
|
|
5
|
-
"failure": -0.
|
|
4
|
+
"success": 0.9999970936785837,
|
|
5
|
+
"failure": -0.3587852317595
|
|
6
6
|
}
|
|
7
7
|
},
|
|
8
8
|
"sequences": {},
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"dirPatterns": {},
|
|
11
11
|
"errorPatterns": [],
|
|
12
12
|
"metrics": {
|
|
13
|
-
"totalRoutes":
|
|
14
|
-
"successfulRoutes":
|
|
13
|
+
"totalRoutes": 133,
|
|
14
|
+
"successfulRoutes": 121,
|
|
15
15
|
"routingHistory": []
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -3,49 +3,49 @@
|
|
|
3
3
|
"startedAt": "2026-01-07T03:07:50.010Z",
|
|
4
4
|
"workers": {
|
|
5
5
|
"map": {
|
|
6
|
-
"runCount":
|
|
7
|
-
"successCount":
|
|
6
|
+
"runCount": 7,
|
|
7
|
+
"successCount": 7,
|
|
8
8
|
"failureCount": 0,
|
|
9
|
-
"averageDurationMs": 0.
|
|
9
|
+
"averageDurationMs": 0.5714285714285714,
|
|
10
10
|
"isRunning": false,
|
|
11
|
-
"nextRun": "2026-01-07T03:
|
|
12
|
-
"lastRun": "2026-01-07T03:
|
|
11
|
+
"nextRun": "2026-01-07T03:37:50.197Z",
|
|
12
|
+
"lastRun": "2026-01-07T03:37:50.198Z"
|
|
13
13
|
},
|
|
14
14
|
"audit": {
|
|
15
|
-
"runCount":
|
|
16
|
-
"successCount":
|
|
15
|
+
"runCount": 4,
|
|
16
|
+
"successCount": 4,
|
|
17
17
|
"failureCount": 0,
|
|
18
|
-
"averageDurationMs": 0.
|
|
18
|
+
"averageDurationMs": 0.25,
|
|
19
19
|
"isRunning": false,
|
|
20
|
-
"nextRun": "2026-01-07T03:
|
|
21
|
-
"lastRun": "2026-01-07T03:
|
|
20
|
+
"nextRun": "2026-01-07T03:47:50.117Z",
|
|
21
|
+
"lastRun": "2026-01-07T03:37:50.117Z"
|
|
22
22
|
},
|
|
23
23
|
"optimize": {
|
|
24
|
-
"runCount":
|
|
25
|
-
"successCount":
|
|
24
|
+
"runCount": 3,
|
|
25
|
+
"successCount": 3,
|
|
26
26
|
"failureCount": 0,
|
|
27
27
|
"averageDurationMs": 0,
|
|
28
28
|
"isRunning": false,
|
|
29
|
-
"nextRun": "2026-01-07T03:
|
|
30
|
-
"lastRun": "2026-01-07T03:
|
|
29
|
+
"nextRun": "2026-01-07T03:52:50.090Z",
|
|
30
|
+
"lastRun": "2026-01-07T03:37:50.089Z"
|
|
31
31
|
},
|
|
32
32
|
"consolidate": {
|
|
33
|
-
"runCount":
|
|
34
|
-
"successCount":
|
|
33
|
+
"runCount": 2,
|
|
34
|
+
"successCount": 2,
|
|
35
35
|
"failureCount": 0,
|
|
36
36
|
"averageDurationMs": 1,
|
|
37
37
|
"isRunning": false,
|
|
38
|
-
"nextRun": "2026-01-
|
|
39
|
-
"lastRun": "2026-01-07T03:
|
|
38
|
+
"nextRun": "2026-01-07T04:07:50.089Z",
|
|
39
|
+
"lastRun": "2026-01-07T03:37:50.089Z"
|
|
40
40
|
},
|
|
41
41
|
"testgaps": {
|
|
42
|
-
"runCount":
|
|
43
|
-
"successCount":
|
|
42
|
+
"runCount": 2,
|
|
43
|
+
"successCount": 2,
|
|
44
44
|
"failureCount": 0,
|
|
45
45
|
"averageDurationMs": 0,
|
|
46
46
|
"isRunning": false,
|
|
47
|
-
"nextRun": "2026-01-07T03:
|
|
48
|
-
"lastRun": "2026-01-07T03:
|
|
47
|
+
"nextRun": "2026-01-07T03:47:50.072Z",
|
|
48
|
+
"lastRun": "2026-01-07T03:27:50.072Z"
|
|
49
49
|
},
|
|
50
50
|
"predict": {
|
|
51
51
|
"runCount": 0,
|
|
@@ -119,5 +119,5 @@
|
|
|
119
119
|
}
|
|
120
120
|
]
|
|
121
121
|
},
|
|
122
|
-
"savedAt": "2026-01-07T03:
|
|
122
|
+
"savedAt": "2026-01-07T03:37:50.198Z"
|
|
123
123
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"timestamp": "2026-01-07T03:
|
|
2
|
+
"timestamp": "2026-01-07T03:37:50.198Z",
|
|
3
3
|
"projectRoot": "/workspaces/claude-flow/v3/@claude-flow/cli",
|
|
4
4
|
"structure": {
|
|
5
5
|
"hasPackageJson": true,
|
|
@@ -7,5 +7,5 @@
|
|
|
7
7
|
"hasClaudeConfig": false,
|
|
8
8
|
"hasClaudeFlow": true
|
|
9
9
|
},
|
|
10
|
-
"scannedAt":
|
|
10
|
+
"scannedAt": 1767757070198
|
|
11
11
|
}
|
|
@@ -1,87 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
"
|
|
14
|
-
"basicOperations": 0,
|
|
15
|
-
"autoModeSelections": 0,
|
|
16
|
-
"modeOverrides": 0,
|
|
17
|
-
"currentMode": "auto"
|
|
18
|
-
},
|
|
19
|
-
"operations": {
|
|
20
|
-
"store": {
|
|
21
|
-
"count": 0,
|
|
22
|
-
"totalDuration": 0,
|
|
23
|
-
"errors": 0
|
|
24
|
-
},
|
|
25
|
-
"retrieve": {
|
|
26
|
-
"count": 0,
|
|
27
|
-
"totalDuration": 0,
|
|
28
|
-
"errors": 0
|
|
29
|
-
},
|
|
30
|
-
"query": {
|
|
31
|
-
"count": 0,
|
|
32
|
-
"totalDuration": 0,
|
|
33
|
-
"errors": 0
|
|
34
|
-
},
|
|
35
|
-
"list": {
|
|
36
|
-
"count": 0,
|
|
37
|
-
"totalDuration": 0,
|
|
38
|
-
"errors": 0
|
|
39
|
-
},
|
|
40
|
-
"delete": {
|
|
41
|
-
"count": 0,
|
|
42
|
-
"totalDuration": 0,
|
|
43
|
-
"errors": 0
|
|
44
|
-
},
|
|
45
|
-
"search": {
|
|
46
|
-
"count": 0,
|
|
47
|
-
"totalDuration": 0,
|
|
48
|
-
"errors": 0
|
|
49
|
-
},
|
|
50
|
-
"init": {
|
|
51
|
-
"count": 0,
|
|
52
|
-
"totalDuration": 0,
|
|
53
|
-
"errors": 0
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
"performance": {
|
|
57
|
-
"avgOperationDuration": 0,
|
|
58
|
-
"minOperationDuration": null,
|
|
59
|
-
"maxOperationDuration": null,
|
|
60
|
-
"slowOperations": 0,
|
|
61
|
-
"fastOperations": 0,
|
|
62
|
-
"totalOperationTime": 0
|
|
63
|
-
},
|
|
64
|
-
"storage": {
|
|
65
|
-
"totalEntries": 0,
|
|
66
|
-
"reasoningbankEntries": 0,
|
|
67
|
-
"basicEntries": 0,
|
|
68
|
-
"databaseSize": 0,
|
|
69
|
-
"lastBackup": null,
|
|
70
|
-
"growthRate": 0
|
|
71
|
-
},
|
|
72
|
-
"errors": {
|
|
73
|
-
"total": 0,
|
|
74
|
-
"byType": {},
|
|
75
|
-
"byOperation": {},
|
|
76
|
-
"recent": []
|
|
77
|
-
},
|
|
78
|
-
"reasoningbank": {
|
|
79
|
-
"semanticSearches": 0,
|
|
80
|
-
"sqlFallbacks": 0,
|
|
81
|
-
"embeddingGenerated": 0,
|
|
82
|
-
"consolidations": 0,
|
|
83
|
-
"avgQueryTime": 0,
|
|
84
|
-
"cacheHits": 0,
|
|
85
|
-
"cacheMisses": 0
|
|
2
|
+
"timestamp": "2026-01-07T03:37:50.090Z",
|
|
3
|
+
"memoryUsage": {
|
|
4
|
+
"rss": 65044480,
|
|
5
|
+
"heapTotal": 11042816,
|
|
6
|
+
"heapUsed": 9247808,
|
|
7
|
+
"external": 2145622,
|
|
8
|
+
"arrayBuffers": 24811
|
|
9
|
+
},
|
|
10
|
+
"uptime": 1594.301482026,
|
|
11
|
+
"optimizations": {
|
|
12
|
+
"cacheHitRate": 0.78,
|
|
13
|
+
"avgResponseTime": 45
|
|
86
14
|
}
|
|
87
15
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[
|
|
2
2
|
{
|
|
3
|
-
"id": "cmd-hooks-
|
|
3
|
+
"id": "cmd-hooks-1767756988616",
|
|
4
4
|
"type": "hooks",
|
|
5
5
|
"success": true,
|
|
6
|
-
"duration":
|
|
7
|
-
"timestamp":
|
|
6
|
+
"duration": 2.273775999999998,
|
|
7
|
+
"timestamp": 1767756988618,
|
|
8
8
|
"metadata": {}
|
|
9
9
|
}
|
|
10
10
|
]
|
package/agents/architect.yaml
CHANGED
package/agents/coder.yaml
CHANGED
package/agents/reviewer.yaml
CHANGED
package/agents/tester.yaml
CHANGED
|
@@ -48,6 +48,11 @@ interface DaemonConfig {
|
|
|
48
48
|
logDir: string;
|
|
49
49
|
stateFile: string;
|
|
50
50
|
maxConcurrent: number;
|
|
51
|
+
workerTimeoutMs: number;
|
|
52
|
+
resourceThresholds: {
|
|
53
|
+
maxCpuLoad: number;
|
|
54
|
+
minFreeMemoryPercent: number;
|
|
55
|
+
};
|
|
51
56
|
workers: WorkerConfig[];
|
|
52
57
|
}
|
|
53
58
|
/**
|
|
@@ -60,7 +65,21 @@ export declare class WorkerDaemon extends EventEmitter {
|
|
|
60
65
|
private running;
|
|
61
66
|
private startedAt?;
|
|
62
67
|
private projectRoot;
|
|
68
|
+
private runningWorkers;
|
|
69
|
+
private pendingWorkers;
|
|
63
70
|
constructor(projectRoot: string, config?: Partial<DaemonConfig>);
|
|
71
|
+
/**
|
|
72
|
+
* Setup graceful shutdown handlers
|
|
73
|
+
*/
|
|
74
|
+
private setupShutdownHandlers;
|
|
75
|
+
/**
|
|
76
|
+
* Check if system resources allow worker execution
|
|
77
|
+
*/
|
|
78
|
+
private canRunWorker;
|
|
79
|
+
/**
|
|
80
|
+
* Process pending workers queue
|
|
81
|
+
*/
|
|
82
|
+
private processPendingWorkers;
|
|
64
83
|
private initializeWorkerStates;
|
|
65
84
|
/**
|
|
66
85
|
* Start the daemon and all enabled workers
|
|
@@ -75,13 +94,21 @@ export declare class WorkerDaemon extends EventEmitter {
|
|
|
75
94
|
*/
|
|
76
95
|
getStatus(): DaemonStatus;
|
|
77
96
|
/**
|
|
78
|
-
* Schedule a worker to run at intervals
|
|
97
|
+
* Schedule a worker to run at intervals with staggered start
|
|
79
98
|
*/
|
|
80
99
|
private scheduleWorker;
|
|
81
100
|
/**
|
|
82
|
-
* Execute a worker
|
|
101
|
+
* Execute a worker with concurrency control (P0 fix)
|
|
102
|
+
*/
|
|
103
|
+
private executeWorkerWithConcurrencyControl;
|
|
104
|
+
/**
|
|
105
|
+
* Execute a worker with timeout protection
|
|
83
106
|
*/
|
|
84
107
|
private executeWorker;
|
|
108
|
+
/**
|
|
109
|
+
* Run a function with timeout (P1 fix)
|
|
110
|
+
*/
|
|
111
|
+
private runWithTimeout;
|
|
85
112
|
/**
|
|
86
113
|
* Run the actual worker logic
|
|
87
114
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-daemon.d.ts","sourceRoot":"","sources":["../../../src/services/worker-daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAKtC,MAAM,MAAM,UAAU,GAClB,YAAY,GACZ,UAAU,GACV,aAAa,GACb,SAAS,GACT,OAAO,GACP,KAAK,GACL,SAAS,GACT,UAAU,GACV,UAAU,GACV,UAAU,GACV,WAAW,GACX,UAAU,CAAC;AAEf,UAAU,YAAY;IACpB,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,UAAU,WAAW;IACnB,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,UAAU,YAAY;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,UAAU,YAAY;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,OAAO,EAAE,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IACtC,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,UAAU,YAAY;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB;
|
|
1
|
+
{"version":3,"file":"worker-daemon.d.ts","sourceRoot":"","sources":["../../../src/services/worker-daemon.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,16 +12,18 @@
|
|
|
12
12
|
import { EventEmitter } from 'events';
|
|
13
13
|
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
|
|
14
14
|
import { join } from 'path';
|
|
15
|
-
// Default worker configurations with intervals
|
|
15
|
+
// Default worker configurations with improved intervals (P0 fix: map 5min -> 15min)
|
|
16
16
|
const DEFAULT_WORKERS = [
|
|
17
|
-
{ type: 'map', intervalMs:
|
|
18
|
-
{ type: 'audit', intervalMs: 10 * 60 * 1000, priority: 'critical', description: 'Security analysis', enabled: true },
|
|
19
|
-
{ type: 'optimize', intervalMs: 15 * 60 * 1000, priority: 'high', description: 'Performance optimization', enabled: true },
|
|
20
|
-
{ type: 'consolidate', intervalMs: 30 * 60 * 1000, priority: 'low', description: 'Memory consolidation', enabled: true },
|
|
21
|
-
{ type: 'testgaps', intervalMs: 20 * 60 * 1000, priority: 'normal', description: 'Test coverage analysis', enabled: true },
|
|
22
|
-
{ type: 'predict', intervalMs:
|
|
23
|
-
{ type: 'document', intervalMs: 60 * 60 * 1000, priority: 'low', description: 'Auto-documentation', enabled: false },
|
|
17
|
+
{ type: 'map', intervalMs: 15 * 60 * 1000, offsetMs: 0, priority: 'normal', description: 'Codebase mapping', enabled: true },
|
|
18
|
+
{ type: 'audit', intervalMs: 10 * 60 * 1000, offsetMs: 2 * 60 * 1000, priority: 'critical', description: 'Security analysis', enabled: true },
|
|
19
|
+
{ type: 'optimize', intervalMs: 15 * 60 * 1000, offsetMs: 4 * 60 * 1000, priority: 'high', description: 'Performance optimization', enabled: true },
|
|
20
|
+
{ type: 'consolidate', intervalMs: 30 * 60 * 1000, offsetMs: 6 * 60 * 1000, priority: 'low', description: 'Memory consolidation', enabled: true },
|
|
21
|
+
{ type: 'testgaps', intervalMs: 20 * 60 * 1000, offsetMs: 8 * 60 * 1000, priority: 'normal', description: 'Test coverage analysis', enabled: true },
|
|
22
|
+
{ type: 'predict', intervalMs: 10 * 60 * 1000, offsetMs: 0, priority: 'low', description: 'Predictive preloading', enabled: false },
|
|
23
|
+
{ type: 'document', intervalMs: 60 * 60 * 1000, offsetMs: 0, priority: 'low', description: 'Auto-documentation', enabled: false },
|
|
24
24
|
];
|
|
25
|
+
// Worker timeout (5 minutes max per worker)
|
|
26
|
+
const DEFAULT_WORKER_TIMEOUT_MS = 5 * 60 * 1000;
|
|
25
27
|
/**
|
|
26
28
|
* Worker Daemon - Manages background workers with Node.js
|
|
27
29
|
*/
|
|
@@ -32,17 +34,26 @@ export class WorkerDaemon extends EventEmitter {
|
|
|
32
34
|
running = false;
|
|
33
35
|
startedAt;
|
|
34
36
|
projectRoot;
|
|
37
|
+
runningWorkers = new Set(); // Track concurrent workers
|
|
38
|
+
pendingWorkers = []; // Queue for deferred workers
|
|
35
39
|
constructor(projectRoot, config) {
|
|
36
40
|
super();
|
|
37
41
|
this.projectRoot = projectRoot;
|
|
38
42
|
const claudeFlowDir = join(projectRoot, '.claude-flow');
|
|
39
43
|
this.config = {
|
|
40
|
-
autoStart: config?.autoStart ??
|
|
44
|
+
autoStart: config?.autoStart ?? false, // P1 fix: Default to false for explicit consent
|
|
41
45
|
logDir: config?.logDir ?? join(claudeFlowDir, 'logs'),
|
|
42
46
|
stateFile: config?.stateFile ?? join(claudeFlowDir, 'daemon-state.json'),
|
|
43
|
-
maxConcurrent: config?.maxConcurrent ??
|
|
47
|
+
maxConcurrent: config?.maxConcurrent ?? 2, // P0 fix: Limit concurrent workers
|
|
48
|
+
workerTimeoutMs: config?.workerTimeoutMs ?? DEFAULT_WORKER_TIMEOUT_MS,
|
|
49
|
+
resourceThresholds: config?.resourceThresholds ?? {
|
|
50
|
+
maxCpuLoad: 2.0,
|
|
51
|
+
minFreeMemoryPercent: 20,
|
|
52
|
+
},
|
|
44
53
|
workers: config?.workers ?? DEFAULT_WORKERS,
|
|
45
54
|
};
|
|
55
|
+
// Setup graceful shutdown handlers
|
|
56
|
+
this.setupShutdownHandlers();
|
|
46
57
|
// Ensure directories exist
|
|
47
58
|
if (!existsSync(claudeFlowDir)) {
|
|
48
59
|
mkdirSync(claudeFlowDir, { recursive: true });
|
|
@@ -53,6 +64,48 @@ export class WorkerDaemon extends EventEmitter {
|
|
|
53
64
|
// Initialize worker states
|
|
54
65
|
this.initializeWorkerStates();
|
|
55
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Setup graceful shutdown handlers
|
|
69
|
+
*/
|
|
70
|
+
setupShutdownHandlers() {
|
|
71
|
+
const shutdown = async () => {
|
|
72
|
+
this.log('info', 'Received shutdown signal, stopping daemon...');
|
|
73
|
+
await this.stop();
|
|
74
|
+
process.exit(0);
|
|
75
|
+
};
|
|
76
|
+
process.on('SIGTERM', shutdown);
|
|
77
|
+
process.on('SIGINT', shutdown);
|
|
78
|
+
process.on('SIGHUP', shutdown);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Check if system resources allow worker execution
|
|
82
|
+
*/
|
|
83
|
+
async canRunWorker() {
|
|
84
|
+
const os = await import('os');
|
|
85
|
+
const cpuLoad = os.loadavg()[0];
|
|
86
|
+
const totalMem = os.totalmem();
|
|
87
|
+
const freeMem = os.freemem();
|
|
88
|
+
const freePercent = (freeMem / totalMem) * 100;
|
|
89
|
+
if (cpuLoad > this.config.resourceThresholds.maxCpuLoad) {
|
|
90
|
+
return { allowed: false, reason: `CPU load too high: ${cpuLoad.toFixed(2)}` };
|
|
91
|
+
}
|
|
92
|
+
if (freePercent < this.config.resourceThresholds.minFreeMemoryPercent) {
|
|
93
|
+
return { allowed: false, reason: `Memory too low: ${freePercent.toFixed(1)}% free` };
|
|
94
|
+
}
|
|
95
|
+
return { allowed: true };
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Process pending workers queue
|
|
99
|
+
*/
|
|
100
|
+
async processPendingWorkers() {
|
|
101
|
+
while (this.pendingWorkers.length > 0 && this.runningWorkers.size < this.config.maxConcurrent) {
|
|
102
|
+
const workerType = this.pendingWorkers.shift();
|
|
103
|
+
const workerConfig = this.config.workers.find(w => w.type === workerType);
|
|
104
|
+
if (workerConfig) {
|
|
105
|
+
await this.executeWorkerWithConcurrencyControl(workerConfig);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
56
109
|
initializeWorkerStates() {
|
|
57
110
|
// Try to restore state from file
|
|
58
111
|
if (existsSync(this.config.stateFile)) {
|
|
@@ -144,21 +197,24 @@ export class WorkerDaemon extends EventEmitter {
|
|
|
144
197
|
};
|
|
145
198
|
}
|
|
146
199
|
/**
|
|
147
|
-
* Schedule a worker to run at intervals
|
|
200
|
+
* Schedule a worker to run at intervals with staggered start
|
|
148
201
|
*/
|
|
149
202
|
scheduleWorker(workerConfig) {
|
|
150
203
|
const state = this.workers.get(workerConfig.type);
|
|
151
|
-
|
|
152
|
-
|
|
204
|
+
const internalConfig = workerConfig;
|
|
205
|
+
const staggerOffset = internalConfig.offsetMs || 0;
|
|
206
|
+
// Calculate initial delay with stagger offset
|
|
207
|
+
let initialDelay = staggerOffset;
|
|
153
208
|
if (state.lastRun) {
|
|
154
209
|
const timeSinceLastRun = Date.now() - state.lastRun.getTime();
|
|
155
|
-
initialDelay = Math.max(
|
|
210
|
+
initialDelay = Math.max(staggerOffset, workerConfig.intervalMs - timeSinceLastRun);
|
|
156
211
|
}
|
|
157
212
|
state.nextRun = new Date(Date.now() + initialDelay);
|
|
158
213
|
const runAndReschedule = async () => {
|
|
159
214
|
if (!this.running)
|
|
160
215
|
return;
|
|
161
|
-
|
|
216
|
+
// Use concurrency-controlled execution (P0 fix)
|
|
217
|
+
await this.executeWorkerWithConcurrencyControl(workerConfig);
|
|
162
218
|
// Reschedule
|
|
163
219
|
if (this.running) {
|
|
164
220
|
const timer = setTimeout(runAndReschedule, workerConfig.intervalMs);
|
|
@@ -166,24 +222,47 @@ export class WorkerDaemon extends EventEmitter {
|
|
|
166
222
|
state.nextRun = new Date(Date.now() + workerConfig.intervalMs);
|
|
167
223
|
}
|
|
168
224
|
};
|
|
169
|
-
// Schedule first run
|
|
225
|
+
// Schedule first run with stagger offset
|
|
170
226
|
const timer = setTimeout(runAndReschedule, initialDelay);
|
|
171
227
|
this.timers.set(workerConfig.type, timer);
|
|
172
228
|
this.log('info', `Scheduled ${workerConfig.type} (interval: ${workerConfig.intervalMs / 1000}s, first run in ${initialDelay / 1000}s)`);
|
|
173
229
|
}
|
|
174
230
|
/**
|
|
175
|
-
* Execute a worker
|
|
231
|
+
* Execute a worker with concurrency control (P0 fix)
|
|
232
|
+
*/
|
|
233
|
+
async executeWorkerWithConcurrencyControl(workerConfig) {
|
|
234
|
+
// Check concurrency limit
|
|
235
|
+
if (this.runningWorkers.size >= this.config.maxConcurrent) {
|
|
236
|
+
this.log('info', `Worker ${workerConfig.type} deferred: max concurrent (${this.config.maxConcurrent}) reached`);
|
|
237
|
+
this.pendingWorkers.push(workerConfig.type);
|
|
238
|
+
this.emit('worker:deferred', { type: workerConfig.type, reason: 'max_concurrent' });
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
// Check resource availability
|
|
242
|
+
const resourceCheck = await this.canRunWorker();
|
|
243
|
+
if (!resourceCheck.allowed) {
|
|
244
|
+
this.log('info', `Worker ${workerConfig.type} deferred: ${resourceCheck.reason}`);
|
|
245
|
+
this.pendingWorkers.push(workerConfig.type);
|
|
246
|
+
this.emit('worker:deferred', { type: workerConfig.type, reason: resourceCheck.reason });
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
return this.executeWorker(workerConfig);
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Execute a worker with timeout protection
|
|
176
253
|
*/
|
|
177
254
|
async executeWorker(workerConfig) {
|
|
178
255
|
const state = this.workers.get(workerConfig.type);
|
|
179
256
|
const workerId = `${workerConfig.type}_${Date.now()}`;
|
|
180
257
|
const startTime = Date.now();
|
|
258
|
+
// Track running worker
|
|
259
|
+
this.runningWorkers.add(workerConfig.type);
|
|
181
260
|
state.isRunning = true;
|
|
182
261
|
this.emit('worker:start', { workerId, type: workerConfig.type });
|
|
183
|
-
this.log('info', `Starting worker: ${workerConfig.type}`);
|
|
262
|
+
this.log('info', `Starting worker: ${workerConfig.type} (${this.runningWorkers.size}/${this.config.maxConcurrent} concurrent)`);
|
|
184
263
|
try {
|
|
185
|
-
// Execute worker logic
|
|
186
|
-
const output = await this.runWorkerLogic(workerConfig);
|
|
264
|
+
// Execute worker logic with timeout (P1 fix)
|
|
265
|
+
const output = await this.runWithTimeout(() => this.runWorkerLogic(workerConfig), this.config.workerTimeoutMs, `Worker ${workerConfig.type} timed out after ${this.config.workerTimeoutMs / 1000}s`);
|
|
187
266
|
const durationMs = Date.now() - startTime;
|
|
188
267
|
// Update state
|
|
189
268
|
state.runCount++;
|
|
@@ -223,6 +302,30 @@ export class WorkerDaemon extends EventEmitter {
|
|
|
223
302
|
this.saveState();
|
|
224
303
|
return result;
|
|
225
304
|
}
|
|
305
|
+
finally {
|
|
306
|
+
// Remove from running set and process queue
|
|
307
|
+
this.runningWorkers.delete(workerConfig.type);
|
|
308
|
+
this.processPendingWorkers();
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Run a function with timeout (P1 fix)
|
|
313
|
+
*/
|
|
314
|
+
async runWithTimeout(fn, timeoutMs, timeoutMessage) {
|
|
315
|
+
return new Promise((resolve, reject) => {
|
|
316
|
+
const timer = setTimeout(() => {
|
|
317
|
+
reject(new Error(timeoutMessage));
|
|
318
|
+
}, timeoutMs);
|
|
319
|
+
fn()
|
|
320
|
+
.then((result) => {
|
|
321
|
+
clearTimeout(timer);
|
|
322
|
+
resolve(result);
|
|
323
|
+
})
|
|
324
|
+
.catch((error) => {
|
|
325
|
+
clearTimeout(timer);
|
|
326
|
+
reject(error);
|
|
327
|
+
});
|
|
328
|
+
});
|
|
226
329
|
}
|
|
227
330
|
/**
|
|
228
331
|
* Run the actual worker logic
|