ppef 1.0.1 → 1.2.0
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/README.md +76 -125
- package/bin/ppef.mjs +20 -0
- package/dist/__tests__/cli/evaluate-command.integration.test.d.ts +8 -0
- package/dist/__tests__/cli/evaluate-command.integration.test.d.ts.map +1 -0
- package/dist/__tests__/cli/evaluate-command.integration.test.js +308 -0
- package/dist/__tests__/cli/evaluate-command.integration.test.js.map +1 -0
- package/dist/__tests__/evaluators/claims-evaluator.unit.test.d.ts +8 -0
- package/dist/__tests__/evaluators/claims-evaluator.unit.test.d.ts.map +1 -0
- package/dist/__tests__/evaluators/claims-evaluator.unit.test.js +405 -0
- package/dist/__tests__/evaluators/claims-evaluator.unit.test.js.map +1 -0
- package/dist/__tests__/evaluators/metrics-evaluator.unit.test.d.ts +8 -0
- package/dist/__tests__/evaluators/metrics-evaluator.unit.test.d.ts.map +1 -0
- package/dist/__tests__/evaluators/metrics-evaluator.unit.test.js +424 -0
- package/dist/__tests__/evaluators/metrics-evaluator.unit.test.js.map +1 -0
- package/dist/__tests__/evaluators/registry.unit.test.d.ts +7 -0
- package/dist/__tests__/evaluators/registry.unit.test.d.ts.map +1 -0
- package/dist/__tests__/evaluators/registry.unit.test.js +173 -0
- package/dist/__tests__/evaluators/registry.unit.test.js.map +1 -0
- package/dist/__tests__/evaluators/robustness-evaluator.unit.test.d.ts +8 -0
- package/dist/__tests__/evaluators/robustness-evaluator.unit.test.d.ts.map +1 -0
- package/dist/__tests__/evaluators/robustness-evaluator.unit.test.js +260 -0
- package/dist/__tests__/evaluators/robustness-evaluator.unit.test.js.map +1 -0
- package/dist/__tests__/framework-pipeline.integration.test.js +49 -20
- package/dist/__tests__/framework-pipeline.integration.test.js.map +1 -1
- package/dist/__tests__/index-exports.unit.test.d.ts +8 -0
- package/dist/__tests__/index-exports.unit.test.d.ts.map +1 -0
- package/dist/__tests__/index-exports.unit.test.js +124 -0
- package/dist/__tests__/index-exports.unit.test.js.map +1 -0
- package/dist/__tests__/registry-executor.integration.test.js +12 -9
- package/dist/__tests__/registry-executor.integration.test.js.map +1 -1
- package/dist/aggregation/__tests__/aggregators.unit.test.d.ts +7 -0
- package/dist/aggregation/__tests__/aggregators.unit.test.d.ts.map +1 -0
- package/dist/aggregation/__tests__/aggregators.unit.test.js +350 -0
- package/dist/aggregation/__tests__/aggregators.unit.test.js.map +1 -0
- package/dist/aggregation/__tests__/pipeline.unit.test.d.ts +7 -0
- package/dist/aggregation/__tests__/pipeline.unit.test.d.ts.map +1 -0
- package/dist/aggregation/__tests__/pipeline.unit.test.js +213 -0
- package/dist/aggregation/__tests__/pipeline.unit.test.js.map +1 -0
- package/dist/aggregation/aggregators.d.ts +9 -0
- package/dist/aggregation/aggregators.d.ts.map +1 -1
- package/dist/aggregation/aggregators.js +1 -1
- package/dist/aggregation/aggregators.js.map +1 -1
- package/dist/aggregation/index.d.ts +1 -1
- package/dist/aggregation/index.d.ts.map +1 -1
- package/dist/aggregation/index.js +1 -1
- package/dist/aggregation/index.js.map +1 -1
- package/dist/aggregation/pipeline.d.ts.map +1 -1
- package/dist/aggregation/pipeline.js +40 -3
- package/dist/aggregation/pipeline.js.map +1 -1
- package/dist/claims/index.d.ts +6 -3
- package/dist/claims/index.d.ts.map +1 -1
- package/dist/claims/index.js +6 -3
- package/dist/claims/index.js.map +1 -1
- package/dist/cli/__tests__/aggregate.command.unit.test.d.ts +7 -0
- package/dist/cli/__tests__/aggregate.command.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/aggregate.command.unit.test.js +399 -0
- package/dist/cli/__tests__/aggregate.command.unit.test.js.map +1 -0
- package/dist/cli/__tests__/binary-sut.integration.test.d.ts +8 -0
- package/dist/cli/__tests__/binary-sut.integration.test.d.ts.map +1 -0
- package/dist/cli/__tests__/binary-sut.integration.test.js +165 -0
- package/dist/cli/__tests__/binary-sut.integration.test.js.map +1 -0
- package/dist/cli/__tests__/commands.unit.test.d.ts +10 -0
- package/dist/cli/__tests__/commands.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/commands.unit.test.js +217 -0
- package/dist/cli/__tests__/commands.unit.test.js.map +1 -0
- package/dist/cli/__tests__/config-loader.unit.test.d.ts +7 -0
- package/dist/cli/__tests__/config-loader.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/config-loader.unit.test.js +611 -0
- package/dist/cli/__tests__/config-loader.unit.test.js.map +1 -0
- package/dist/cli/__tests__/index.unit.test.d.ts +10 -0
- package/dist/cli/__tests__/index.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/index.unit.test.js +65 -0
- package/dist/cli/__tests__/index.unit.test.js.map +1 -0
- package/dist/cli/__tests__/logger.unit.test.d.ts +11 -0
- package/dist/cli/__tests__/logger.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/logger.unit.test.js +180 -0
- package/dist/cli/__tests__/logger.unit.test.js.map +1 -0
- package/dist/cli/__tests__/module-loader.unit.test.d.ts +11 -0
- package/dist/cli/__tests__/module-loader.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/module-loader.unit.test.js +262 -0
- package/dist/cli/__tests__/module-loader.unit.test.js.map +1 -0
- package/dist/cli/__tests__/output-writer.unit.test.d.ts +10 -0
- package/dist/cli/__tests__/output-writer.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/output-writer.unit.test.js +216 -0
- package/dist/cli/__tests__/output-writer.unit.test.js.map +1 -0
- package/dist/cli/__tests__/plan.command.unit.test.d.ts +7 -0
- package/dist/cli/__tests__/plan.command.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/plan.command.unit.test.js +289 -0
- package/dist/cli/__tests__/plan.command.unit.test.js.map +1 -0
- package/dist/cli/__tests__/run.command.unit.test.d.ts +7 -0
- package/dist/cli/__tests__/run.command.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/run.command.unit.test.js +422 -0
- package/dist/cli/__tests__/run.command.unit.test.js.map +1 -0
- package/dist/cli/__tests__/validate.command.unit.test.d.ts +7 -0
- package/dist/cli/__tests__/validate.command.unit.test.d.ts.map +1 -0
- package/dist/cli/__tests__/validate.command.unit.test.js +226 -0
- package/dist/cli/__tests__/validate.command.unit.test.js.map +1 -0
- package/dist/cli/command-deps.d.ts +137 -0
- package/dist/cli/command-deps.d.ts.map +1 -0
- package/dist/cli/command-deps.js +7 -0
- package/dist/cli/command-deps.js.map +1 -0
- package/dist/cli/commands/aggregate.d.ts +35 -0
- package/dist/cli/commands/aggregate.d.ts.map +1 -0
- package/dist/cli/commands/aggregate.js +124 -0
- package/dist/cli/commands/aggregate.js.map +1 -0
- package/dist/cli/commands/evaluate.d.ts +41 -0
- package/dist/cli/commands/evaluate.d.ts.map +1 -0
- package/dist/cli/commands/evaluate.js +287 -0
- package/dist/cli/commands/evaluate.js.map +1 -0
- package/dist/cli/commands/plan.d.ts +36 -0
- package/dist/cli/commands/plan.d.ts.map +1 -0
- package/dist/cli/commands/plan.js +109 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/run.d.ts +33 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +277 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +27 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +88 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/config-loader.d.ts +30 -0
- package/dist/cli/config-loader.d.ts.map +1 -0
- package/dist/cli/config-loader.js +181 -0
- package/dist/cli/config-loader.js.map +1 -0
- package/dist/cli/index.d.ts +27 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +60 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/logger.d.ts +75 -0
- package/dist/cli/logger.d.ts.map +1 -0
- package/dist/cli/logger.js +131 -0
- package/dist/cli/logger.js.map +1 -0
- package/dist/cli/module-loader.d.ts +68 -0
- package/dist/cli/module-loader.d.ts.map +1 -0
- package/dist/cli/module-loader.js +134 -0
- package/dist/cli/module-loader.js.map +1 -0
- package/dist/cli/output-writer.d.ts +51 -0
- package/dist/cli/output-writer.d.ts.map +1 -0
- package/dist/cli/output-writer.js +65 -0
- package/dist/cli/output-writer.js.map +1 -0
- package/dist/cli/types.d.ts +193 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +7 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/collector/__tests__/result-collector.unit.test.d.ts +7 -0
- package/dist/collector/__tests__/result-collector.unit.test.d.ts.map +1 -0
- package/dist/collector/__tests__/result-collector.unit.test.js +1021 -0
- package/dist/collector/__tests__/result-collector.unit.test.js.map +1 -0
- package/dist/collector/__tests__/schema.unit.test.d.ts +7 -0
- package/dist/collector/__tests__/schema.unit.test.d.ts.map +1 -0
- package/dist/collector/__tests__/schema.unit.test.js +360 -0
- package/dist/collector/__tests__/schema.unit.test.js.map +1 -0
- package/dist/evaluators/claims-evaluator.d.ts +87 -0
- package/dist/evaluators/claims-evaluator.d.ts.map +1 -0
- package/dist/evaluators/claims-evaluator.js +289 -0
- package/dist/evaluators/claims-evaluator.js.map +1 -0
- package/dist/evaluators/exploratory-evaluator.d.ts +136 -0
- package/dist/evaluators/exploratory-evaluator.d.ts.map +1 -0
- package/dist/evaluators/exploratory-evaluator.js +545 -0
- package/dist/evaluators/exploratory-evaluator.js.map +1 -0
- package/dist/evaluators/index.d.ts +13 -0
- package/dist/evaluators/index.d.ts.map +1 -0
- package/dist/evaluators/index.js +14 -0
- package/dist/evaluators/index.js.map +1 -0
- package/dist/evaluators/metrics-evaluator.d.ts +114 -0
- package/dist/evaluators/metrics-evaluator.d.ts.map +1 -0
- package/dist/evaluators/metrics-evaluator.js +433 -0
- package/dist/evaluators/metrics-evaluator.js.map +1 -0
- package/dist/evaluators/registry.d.ts +106 -0
- package/dist/evaluators/registry.d.ts.map +1 -0
- package/dist/evaluators/registry.js +148 -0
- package/dist/evaluators/registry.js.map +1 -0
- package/dist/evaluators/robustness-evaluator.d.ts +57 -0
- package/dist/evaluators/robustness-evaluator.d.ts.map +1 -0
- package/dist/evaluators/robustness-evaluator.js +186 -0
- package/dist/evaluators/robustness-evaluator.js.map +1 -0
- package/dist/executor/__tests__/binary-sut.unit.test.d.ts +8 -0
- package/dist/executor/__tests__/binary-sut.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/binary-sut.unit.test.js +313 -0
- package/dist/executor/__tests__/binary-sut.unit.test.js.map +1 -0
- package/dist/executor/__tests__/checkpoint-manager.unit.test.js +83 -1
- package/dist/executor/__tests__/checkpoint-manager.unit.test.js.map +1 -1
- package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.d.ts +3 -6
- package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.d.ts.map +1 -1
- package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.js +428 -159
- package/dist/executor/__tests__/checkpoint-merge-bug.diagnostic.test.js.map +1 -1
- package/dist/executor/__tests__/checkpoint-storage.unit.test.js +148 -1
- package/dist/executor/__tests__/checkpoint-storage.unit.test.js.map +1 -1
- package/dist/executor/__tests__/executor.unit.test.js +123 -8
- package/dist/executor/__tests__/executor.unit.test.js.map +1 -1
- package/dist/executor/__tests__/memory-monitor.unit.test.d.ts +7 -0
- package/dist/executor/__tests__/memory-monitor.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/memory-monitor.unit.test.js +285 -0
- package/dist/executor/__tests__/memory-monitor.unit.test.js.map +1 -0
- package/dist/executor/__tests__/parallel-executor.unit.test.d.ts +2 -1
- package/dist/executor/__tests__/parallel-executor.unit.test.d.ts.map +1 -1
- package/dist/executor/__tests__/parallel-executor.unit.test.js +426 -156
- package/dist/executor/__tests__/parallel-executor.unit.test.js.map +1 -1
- package/dist/executor/__tests__/resource-calculator.unit.test.d.ts +10 -0
- package/dist/executor/__tests__/resource-calculator.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/resource-calculator.unit.test.js +104 -0
- package/dist/executor/__tests__/resource-calculator.unit.test.js.map +1 -0
- package/dist/executor/__tests__/run-id.unit.test.d.ts +8 -0
- package/dist/executor/__tests__/run-id.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/run-id.unit.test.js +156 -0
- package/dist/executor/__tests__/run-id.unit.test.js.map +1 -0
- package/dist/executor/__tests__/worker-entry.integration.test.d.ts +24 -0
- package/dist/executor/__tests__/worker-entry.integration.test.d.ts.map +1 -0
- package/dist/executor/__tests__/worker-entry.integration.test.js +82 -0
- package/dist/executor/__tests__/worker-entry.integration.test.js.map +1 -0
- package/dist/executor/__tests__/worker-entry.unit.test.d.ts +7 -0
- package/dist/executor/__tests__/worker-entry.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/worker-entry.unit.test.js +364 -0
- package/dist/executor/__tests__/worker-entry.unit.test.js.map +1 -0
- package/dist/executor/__tests__/worker-threads-executor.unit.test.d.ts +8 -0
- package/dist/executor/__tests__/worker-threads-executor.unit.test.d.ts.map +1 -0
- package/dist/executor/__tests__/worker-threads-executor.unit.test.js +276 -0
- package/dist/executor/__tests__/worker-threads-executor.unit.test.js.map +1 -0
- package/dist/executor/binary-sut.d.ts +105 -0
- package/dist/executor/binary-sut.d.ts.map +1 -0
- package/dist/executor/binary-sut.js +174 -0
- package/dist/executor/binary-sut.js.map +1 -0
- package/dist/executor/checkpoint-storage.d.ts.map +1 -1
- package/dist/executor/checkpoint-storage.js +6 -4
- package/dist/executor/checkpoint-storage.js.map +1 -1
- package/dist/executor/executor.d.ts +28 -0
- package/dist/executor/executor.d.ts.map +1 -1
- package/dist/executor/executor.js +85 -24
- package/dist/executor/executor.js.map +1 -1
- package/dist/executor/index.d.ts +4 -0
- package/dist/executor/index.d.ts.map +1 -1
- package/dist/executor/index.js +4 -0
- package/dist/executor/index.js.map +1 -1
- package/dist/executor/parallel-executor.d.ts +186 -0
- package/dist/executor/parallel-executor.d.ts.map +1 -1
- package/dist/executor/parallel-executor.js +218 -83
- package/dist/executor/parallel-executor.js.map +1 -1
- package/dist/executor/resource-calculator.d.ts +49 -0
- package/dist/executor/resource-calculator.d.ts.map +1 -0
- package/dist/executor/resource-calculator.js +129 -0
- package/dist/executor/resource-calculator.js.map +1 -0
- package/dist/executor/run-id.d.ts.map +1 -1
- package/dist/executor/run-id.js +8 -1
- package/dist/executor/run-id.js.map +1 -1
- package/dist/executor/worker-entry.d.ts +2 -0
- package/dist/executor/worker-entry.d.ts.map +1 -1
- package/dist/executor/worker-entry.js +46 -55
- package/dist/executor/worker-entry.js.map +1 -1
- package/dist/executor/worker-executor.d.ts +257 -0
- package/dist/executor/worker-executor.d.ts.map +1 -0
- package/dist/executor/worker-executor.js +308 -0
- package/dist/executor/worker-executor.js.map +1 -0
- package/dist/executor/worker-threads-executor.d.ts +245 -0
- package/dist/executor/worker-threads-executor.d.ts.map +1 -0
- package/dist/executor/worker-threads-executor.js +332 -0
- package/dist/executor/worker-threads-executor.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/renderers/latex-renderer.d.ts +60 -0
- package/dist/renderers/latex-renderer.d.ts.map +1 -1
- package/dist/renderers/latex-renderer.js +299 -0
- package/dist/renderers/latex-renderer.js.map +1 -1
- package/dist/renderers/types.d.ts +9 -0
- package/dist/renderers/types.d.ts.map +1 -1
- package/dist/renderers/types.js.map +1 -1
- package/dist/robustness/__tests__/perturbations.unit.test.d.ts +11 -0
- package/dist/robustness/__tests__/perturbations.unit.test.d.ts.map +1 -0
- package/dist/robustness/__tests__/perturbations.unit.test.js +284 -0
- package/dist/robustness/__tests__/perturbations.unit.test.js.map +1 -0
- package/dist/robustness/index.d.ts +5 -2
- package/dist/robustness/index.d.ts.map +1 -1
- package/dist/robustness/index.js +4 -2
- package/dist/robustness/index.js.map +1 -1
- package/dist/statistical/__tests__/mann-whitney-u.unit.test.d.ts +7 -0
- package/dist/statistical/__tests__/mann-whitney-u.unit.test.d.ts.map +1 -0
- package/dist/statistical/__tests__/mann-whitney-u.unit.test.js +185 -0
- package/dist/statistical/__tests__/mann-whitney-u.unit.test.js.map +1 -0
- package/dist/types/evaluator.d.ts +449 -0
- package/dist/types/evaluator.d.ts.map +1 -0
- package/dist/types/evaluator.js +9 -0
- package/dist/types/evaluator.js.map +1 -0
- package/dist/types/result.d.ts +2 -0
- package/dist/types/result.d.ts.map +1 -1
- package/package.json +8 -1
- package/dist/claims/evaluator.d.ts +0 -33
- package/dist/claims/evaluator.d.ts.map +0 -1
- package/dist/claims/evaluator.js +0 -174
- package/dist/claims/evaluator.js.map +0 -1
- package/dist/robustness/analyzer.d.ts +0 -61
- package/dist/robustness/analyzer.d.ts.map +0 -1
- package/dist/robustness/analyzer.js +0 -191
- package/dist/robustness/analyzer.js.map +0 -1
|
@@ -8,36 +8,77 @@
|
|
|
8
8
|
* results/execute/checkpoint-worker-00.json
|
|
9
9
|
* results/execute/checkpoint-worker-01.json
|
|
10
10
|
* ...
|
|
11
|
+
*
|
|
12
|
+
* Dependency Injection:
|
|
13
|
+
* - Logger interface enables testing of log output
|
|
14
|
+
* - ProcessSpawner interface enables mocking spawn() calls
|
|
15
|
+
* - SystemInfo interface enables testing CPU count and node path logic
|
|
11
16
|
*/
|
|
12
17
|
import { spawn } from "node:child_process";
|
|
13
18
|
import { randomBytes } from "node:crypto";
|
|
14
19
|
import { cpus } from "node:os";
|
|
15
20
|
import { dirname, resolve } from "node:path";
|
|
16
21
|
/**
|
|
17
|
-
*
|
|
18
|
-
* The CLI entry point is dist/cli.js, so we go up one level from there.
|
|
22
|
+
* Production logger using console.
|
|
19
23
|
*/
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const entryPoint = process.argv[1];
|
|
24
|
-
// Resolve to absolute path first (handles relative paths like "dist/cli.js")
|
|
25
|
-
const absoluteEntry = resolve(entryPoint);
|
|
26
|
-
const entryDir = dirname(absoluteEntry);
|
|
27
|
-
// If entry point is in dist/, go up one level to get package root
|
|
28
|
-
if (entryDir.endsWith("/dist") || entryDir.endsWith(String.raw `\dist`)) {
|
|
29
|
-
return entryDir.slice(0, -5); // Remove "/dist"
|
|
24
|
+
export class ConsoleLogger {
|
|
25
|
+
log(message) {
|
|
26
|
+
console.log(message);
|
|
30
27
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
28
|
+
debug(message) {
|
|
29
|
+
console.log(message);
|
|
30
|
+
}
|
|
31
|
+
info(message) {
|
|
32
|
+
console.log(message);
|
|
33
|
+
}
|
|
34
|
+
warn(message) {
|
|
35
|
+
console.warn(message);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Production process spawner using node:child_process.
|
|
40
|
+
*/
|
|
41
|
+
export class ProcessSpawner {
|
|
42
|
+
spawn(command, args, options) {
|
|
43
|
+
return spawn(command, args, options);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Production system info using node:os and process.
|
|
48
|
+
*/
|
|
49
|
+
export class SystemInfo {
|
|
50
|
+
cpuCount = cpus().length;
|
|
51
|
+
nodePath = process.execPath;
|
|
52
|
+
env = process.env;
|
|
53
|
+
packageRoot;
|
|
54
|
+
constructor() {
|
|
55
|
+
this.packageRoot = this.getPackageRoot();
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get the package root directory by resolving from the entry point script.
|
|
59
|
+
* The CLI entry point is dist/cli.js, so we go up one level from there.
|
|
60
|
+
*/
|
|
61
|
+
getPackageRoot() {
|
|
62
|
+
// Get the directory containing the entry point script
|
|
63
|
+
// process.argv[1] is the path to the executed script (e.g., /path/to/graphbox/dist/cli.js)
|
|
64
|
+
const entryPoint = process.argv[1];
|
|
65
|
+
// Resolve to absolute path first (handles relative paths like "dist/cli.js")
|
|
66
|
+
const absoluteEntry = resolve(entryPoint);
|
|
67
|
+
const entryDir = dirname(absoluteEntry);
|
|
68
|
+
// If entry point is in dist/, go up one level to get package root
|
|
69
|
+
if (entryDir.endsWith("/dist") || entryDir.endsWith(String.raw `\dist`)) {
|
|
70
|
+
return entryDir.slice(0, -5); // Remove "/dist"
|
|
71
|
+
}
|
|
72
|
+
// Fallback: use current directory
|
|
73
|
+
return process.cwd();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
35
76
|
/**
|
|
36
77
|
* Generate random worker names using tech-themed adjectives.
|
|
37
78
|
* Returns unique names for each worker.
|
|
38
79
|
* @param count
|
|
39
80
|
*/
|
|
40
|
-
const generateWorkerNames = (count) => {
|
|
81
|
+
export const generateWorkerNames = (count) => {
|
|
41
82
|
const adjectives = [
|
|
42
83
|
"swift",
|
|
43
84
|
"nimble",
|
|
@@ -111,84 +152,178 @@ const generateWorkerNames = (count) => {
|
|
|
111
152
|
* @returns Path to the worker's checkpoint file
|
|
112
153
|
*/
|
|
113
154
|
export const shardPath = (checkpointDir, workerIndex) => resolve(checkpointDir, `checkpoint-worker-${String(workerIndex).padStart(2, "0")}.json`);
|
|
155
|
+
/**
|
|
156
|
+
* Parallel executor class with dependency injection.
|
|
157
|
+
*
|
|
158
|
+
* Spawns multiple Node.js processes, each executing a subset of runs.
|
|
159
|
+
* Each worker writes to its own sharded checkpoint file to avoid race conditions.
|
|
160
|
+
*/
|
|
161
|
+
export class ParallelExecutor {
|
|
162
|
+
logger;
|
|
163
|
+
spawner;
|
|
164
|
+
systemInfo;
|
|
165
|
+
constructor(logger, spawner, systemInfo) {
|
|
166
|
+
this.logger = logger ?? new ConsoleLogger();
|
|
167
|
+
this.spawner = spawner ?? new ProcessSpawner();
|
|
168
|
+
this.systemInfo = systemInfo ?? new SystemInfo();
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Split runs into batches for parallel processing.
|
|
172
|
+
* @param runs - Runs to distribute
|
|
173
|
+
* @param numberWorkers - Number of worker processes
|
|
174
|
+
* @returns Array of run batches
|
|
175
|
+
*/
|
|
176
|
+
_createBatches(runs, numberWorkers) {
|
|
177
|
+
const batchSize = Math.ceil(runs.length / numberWorkers);
|
|
178
|
+
const batches = [];
|
|
179
|
+
for (let i = 0; i < runs.length; i += batchSize) {
|
|
180
|
+
const batch = runs.slice(i, i + batchSize);
|
|
181
|
+
const batchIndex = Math.floor(i / batchSize);
|
|
182
|
+
const runIds = new Set(batch.map((r) => r.runId));
|
|
183
|
+
batches.push({
|
|
184
|
+
index: batchIndex,
|
|
185
|
+
runIds: [...runIds],
|
|
186
|
+
filter: JSON.stringify([...runIds]),
|
|
187
|
+
firstRunId: batch[0]?.runId ?? "none",
|
|
188
|
+
lastRunId: batch.at(-1)?.runId ?? "none",
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
return batches;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Create worker configurations for all batches.
|
|
195
|
+
* @param batches - Run batches
|
|
196
|
+
* @param workerNames - Names for each worker
|
|
197
|
+
* @param cliPath - Path to CLI entry point
|
|
198
|
+
* @param checkpointDir - Base checkpoint directory
|
|
199
|
+
* @param timeoutMs - Per-run timeout in milliseconds
|
|
200
|
+
* @returns Array of worker configurations
|
|
201
|
+
*/
|
|
202
|
+
_createWorkerConfigs(batches, workerNames, cliPath, checkpointDir, timeoutMs) {
|
|
203
|
+
return batches.map((batch) => {
|
|
204
|
+
const workerName = workerNames[batch.index];
|
|
205
|
+
const workerCheckpointPath = shardPath(checkpointDir, batch.index);
|
|
206
|
+
const arguments_ = [
|
|
207
|
+
cliPath,
|
|
208
|
+
"evaluate",
|
|
209
|
+
"--phase=execute",
|
|
210
|
+
"--checkpoint-mode=file",
|
|
211
|
+
`--run-filter=${batch.filter}`,
|
|
212
|
+
];
|
|
213
|
+
// Add timeout if specified
|
|
214
|
+
if (timeoutMs > 0) {
|
|
215
|
+
arguments_.push(`--timeout=${timeoutMs}`);
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
index: batch.index,
|
|
219
|
+
name: workerName,
|
|
220
|
+
checkpointPath: workerCheckpointPath,
|
|
221
|
+
arguments: arguments_,
|
|
222
|
+
env: {
|
|
223
|
+
...this.systemInfo.env,
|
|
224
|
+
NODE_OPTIONS: "--max-old-space-size=4096",
|
|
225
|
+
GRAPHBOX_WORKER_NAME: workerName,
|
|
226
|
+
GRAPHBOX_WORKER_INDEX: batch.index.toString(),
|
|
227
|
+
GRAPHBOX_TOTAL_WORKERS: batches.length.toString(),
|
|
228
|
+
GRAPHBOX_CHECKPOINT_DIR: checkpointDir,
|
|
229
|
+
GRAPHBOX_CHECKPOINT_PATH: workerCheckpointPath,
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Spawn worker processes for all configurations.
|
|
236
|
+
* @param workerConfigs - Worker configurations
|
|
237
|
+
* @param nodePath - Path to node executable
|
|
238
|
+
* @param packageRoot - Package root directory
|
|
239
|
+
* @returns Array of child processes
|
|
240
|
+
*/
|
|
241
|
+
_spawnWorkers(workerConfigs, nodePath, packageRoot) {
|
|
242
|
+
return workerConfigs.map((config) => {
|
|
243
|
+
this.logger.debug(`Spawning worker ${config.index}: ${config.name} with ${config.arguments.length} args`);
|
|
244
|
+
return this.spawner.spawn(nodePath, config.arguments, {
|
|
245
|
+
stdio: "inherit",
|
|
246
|
+
cwd: packageRoot,
|
|
247
|
+
env: config.env,
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Wait for all workers to complete.
|
|
253
|
+
* @param workers - Child processes
|
|
254
|
+
* @returns Promise that resolves when all workers exit
|
|
255
|
+
*/
|
|
256
|
+
async _waitForWorkers(workers) {
|
|
257
|
+
return Promise.all(workers.map((w) => new Promise((resolve) => {
|
|
258
|
+
w.on("exit", (code) => {
|
|
259
|
+
resolve(code);
|
|
260
|
+
});
|
|
261
|
+
})));
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Execute runs using multiple parallel processes.
|
|
265
|
+
*
|
|
266
|
+
* Each worker writes to its own sharded checkpoint file to avoid race conditions.
|
|
267
|
+
* After all workers complete, the main process should merge the shards.
|
|
268
|
+
*
|
|
269
|
+
* @param runs - Planned runs to execute
|
|
270
|
+
* @param suts - SUT definitions (not used directly, passed to workers)
|
|
271
|
+
* @param cases - Case definitions (not used directly, passed to workers)
|
|
272
|
+
* @param config - Executor configuration
|
|
273
|
+
* @param options - Parallel executor options
|
|
274
|
+
* @returns Execution results (empty - CLI will load from shards)
|
|
275
|
+
*/
|
|
276
|
+
async execute(runs, _suts, _cases, config, options = {}) {
|
|
277
|
+
const numberWorkers = options.workers ?? this.systemInfo.cpuCount;
|
|
278
|
+
const nodePath = options.nodePath ?? this.systemInfo.nodePath;
|
|
279
|
+
const checkpointDir = options.checkpointDir ?? resolve(this.systemInfo.packageRoot, "results/execute");
|
|
280
|
+
const timeoutMs = options.timeoutMs ?? config.timeoutMs;
|
|
281
|
+
this.logger.info(`ParallelExecutor: Spawning ${numberWorkers} processes for ${runs.length} runs`);
|
|
282
|
+
this.logger.info(`Checkpoint directory: ${checkpointDir}`);
|
|
283
|
+
if (timeoutMs > 0) {
|
|
284
|
+
this.logger.info(`Per-run timeout: ${timeoutMs}ms (${Math.round(timeoutMs / 1000)}s)`);
|
|
285
|
+
}
|
|
286
|
+
// Generate unique names for each worker
|
|
287
|
+
const workerNames = generateWorkerNames(numberWorkers);
|
|
288
|
+
this.logger.info(`Workers: ${workerNames.map((name, index) => `${index + 1}. ${name}`).join(", ")}`);
|
|
289
|
+
// Split runs into batches
|
|
290
|
+
const batches = this._createBatches(runs, numberWorkers);
|
|
291
|
+
// Log batch information
|
|
292
|
+
for (const batch of batches) {
|
|
293
|
+
this.logger.debug(`Batch ${batch.index} has ${batch.runIds.length} runs, filter length: ${batch.filter.length}`);
|
|
294
|
+
this.logger.debug(` First run: ${batch.firstRunId}, Last run: ${batch.lastRunId}`);
|
|
295
|
+
}
|
|
296
|
+
// Create worker configurations
|
|
297
|
+
const cliPath = resolve(this.systemInfo.packageRoot, "dist/cli.js");
|
|
298
|
+
const workerConfigs = this._createWorkerConfigs(batches, workerNames, cliPath, checkpointDir, timeoutMs);
|
|
299
|
+
// Spawn worker processes
|
|
300
|
+
const workers = this._spawnWorkers(workerConfigs, nodePath, this.systemInfo.packageRoot);
|
|
301
|
+
// Wait for all workers to complete
|
|
302
|
+
const exitCodes = await this._waitForWorkers(workers);
|
|
303
|
+
this.logger.debug(`All workers exited with codes: ${exitCodes.join(", ")}`);
|
|
304
|
+
// Load and return aggregated results
|
|
305
|
+
// For now, return empty - the CLI will handle results and merge shards
|
|
306
|
+
return { results: [], errors: [] };
|
|
307
|
+
}
|
|
308
|
+
}
|
|
114
309
|
/**
|
|
115
310
|
* Execute runs using multiple parallel processes.
|
|
116
311
|
*
|
|
117
312
|
* Each worker writes to its own sharded checkpoint file to avoid race conditions.
|
|
118
313
|
* After all workers complete, the main process should merge the shards.
|
|
119
314
|
*
|
|
315
|
+
* This is a convenience function that creates a ParallelExecutor with default dependencies.
|
|
316
|
+
* For testing or custom behavior, use the ParallelExecutor class directly.
|
|
317
|
+
*
|
|
120
318
|
* @param runs - Planned runs to execute
|
|
121
319
|
* @param suts - SUT definitions (not used directly, passed to workers)
|
|
122
320
|
* @param cases - Case definitions (not used directly, passed to workers)
|
|
123
321
|
* @param config - Executor configuration
|
|
124
322
|
* @param options - Parallel executor options
|
|
323
|
+
* @returns Execution results (empty - CLI will load from shards)
|
|
125
324
|
*/
|
|
126
325
|
export const executeParallel = async (runs, suts, cases, config, options = {}) => {
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
const checkpointDir = options.checkpointDir ?? resolve(PACKAGE_ROOT, "results/execute");
|
|
130
|
-
const timeoutMs = options.timeoutMs ?? config.timeoutMs;
|
|
131
|
-
console.log(`ParallelExecutor: Spawning ${numberWorkers} processes for ${runs.length} runs`);
|
|
132
|
-
console.log(`Checkpoint directory: ${checkpointDir}`);
|
|
133
|
-
if (timeoutMs > 0) {
|
|
134
|
-
console.log(`Per-run timeout: ${timeoutMs}ms (${Math.round(timeoutMs / 1000)}s)`);
|
|
135
|
-
}
|
|
136
|
-
// Generate unique names for each worker
|
|
137
|
-
const workerNames = generateWorkerNames(numberWorkers);
|
|
138
|
-
console.log(`Workers: ${workerNames.map((name, index) => `${index + 1}. ${name}`).join(", ")}`);
|
|
139
|
-
// Split runs into batches
|
|
140
|
-
const batchSize = Math.ceil(runs.length / numberWorkers);
|
|
141
|
-
const batches = [];
|
|
142
|
-
for (let index = 0; index < runs.length; index += batchSize) {
|
|
143
|
-
batches.push(runs.slice(index, index + batchSize));
|
|
144
|
-
}
|
|
145
|
-
// Create a run filter function for each batch
|
|
146
|
-
const runFilters = batches.map((batch, _index) => {
|
|
147
|
-
const runIds = new Set(batch.map((r) => r.runId));
|
|
148
|
-
const filter = JSON.stringify([...runIds]);
|
|
149
|
-
const firstRunId = batch[0]?.runId ?? "none";
|
|
150
|
-
const lastRunId = batch.at(-1)?.runId ?? "none";
|
|
151
|
-
console.log(`DEBUG: Batch ${_index} has ${batch.length} runs, filter length: ${filter.length}`);
|
|
152
|
-
console.log(`DEBUG: First run: ${firstRunId}, Last run: ${lastRunId}`);
|
|
153
|
-
return filter;
|
|
154
|
-
});
|
|
155
|
-
// Spawn worker processes
|
|
156
|
-
const workers = runFilters.map((runFilter, index) => {
|
|
157
|
-
const workerName = workerNames[index];
|
|
158
|
-
const workerCheckpointPath = shardPath(checkpointDir, index);
|
|
159
|
-
const arguments_ = [
|
|
160
|
-
resolve(PACKAGE_ROOT, "dist/cli.js"),
|
|
161
|
-
"evaluate",
|
|
162
|
-
"--phase=execute",
|
|
163
|
-
"--checkpoint-mode=file",
|
|
164
|
-
`--run-filter=${runFilter}`, // JSON array - needs to be quoted in shell but spawn() handles this
|
|
165
|
-
];
|
|
166
|
-
// Add timeout if specified
|
|
167
|
-
if (timeoutMs > 0) {
|
|
168
|
-
arguments_.push(`--timeout=${timeoutMs}`);
|
|
169
|
-
}
|
|
170
|
-
return spawn(nodePath, arguments_, {
|
|
171
|
-
stdio: "inherit",
|
|
172
|
-
cwd: PACKAGE_ROOT, // Ensure workers use the package root as working directory
|
|
173
|
-
env: {
|
|
174
|
-
...process.env,
|
|
175
|
-
NODE_OPTIONS: "--max-old-space-size=4096",
|
|
176
|
-
GRAPHBOX_WORKER_NAME: workerName,
|
|
177
|
-
GRAPHBOX_WORKER_INDEX: index.toString(),
|
|
178
|
-
GRAPHBOX_TOTAL_WORKERS: numberWorkers.toString(),
|
|
179
|
-
GRAPHBOX_CHECKPOINT_DIR: checkpointDir,
|
|
180
|
-
GRAPHBOX_CHECKPOINT_PATH: workerCheckpointPath,
|
|
181
|
-
},
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
// Wait for all workers to complete
|
|
185
|
-
await Promise.all(workers.map((w) => new Promise((resolve) => {
|
|
186
|
-
w.on("exit", (code) => {
|
|
187
|
-
resolve(code);
|
|
188
|
-
});
|
|
189
|
-
})));
|
|
190
|
-
// Load and return aggregated results
|
|
191
|
-
// For now, return empty - the CLI will handle results and merge shards
|
|
192
|
-
return { results: [], errors: [] };
|
|
326
|
+
const executor = new ParallelExecutor();
|
|
327
|
+
return executor.execute(runs, suts, cases, config, options);
|
|
193
328
|
};
|
|
194
329
|
//# sourceMappingURL=parallel-executor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parallel-executor.js","sourceRoot":"","sources":["../../src/executor/parallel-executor.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"parallel-executor.js","sourceRoot":"","sources":["../../src/executor/parallel-executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resource Calculator
|
|
3
|
+
*
|
|
4
|
+
* Automatically calculates optimal resource limits for parallel execution
|
|
5
|
+
* using the "75% rule" - reserves 75% of available resources for workers,
|
|
6
|
+
* leaving 25% for system stability and other processes.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - CPU-based worker count (75% of available cores)
|
|
10
|
+
* - Memory per worker calculation (total memory / worker count)
|
|
11
|
+
* - Dynamic disk I/O ceiling measurement (detects throughput plateau)
|
|
12
|
+
* - Caching to avoid repeated measurements
|
|
13
|
+
*
|
|
14
|
+
* Disk I/O Measurement Algorithm:
|
|
15
|
+
* 1. Test concurrent write+read operations at increasing levels (1, 6, 11, 16, ...)
|
|
16
|
+
* 2. Measure throughput (MB/s) for each concurrency level
|
|
17
|
+
* 3. Detect when throughput plateaus (<5% improvement)
|
|
18
|
+
* 4. Return 75% of the detected ceiling
|
|
19
|
+
* 5. Cache result to avoid re-measuring
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Resource limits for parallel execution.
|
|
23
|
+
*/
|
|
24
|
+
export interface ResourceLimits {
|
|
25
|
+
/** Maximum number of worker threads to spawn */
|
|
26
|
+
maxWorkers: number;
|
|
27
|
+
/** Maximum memory per worker in MB */
|
|
28
|
+
maxMemoryMb: number;
|
|
29
|
+
/** Maximum concurrent I/O operations */
|
|
30
|
+
maxConcurrentIo: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Calculate resource limits using the 75% rule.
|
|
34
|
+
*
|
|
35
|
+
* @param reservePercent - Percentage of resources to reserve (default: 0.75 for 75%)
|
|
36
|
+
* @param options - Options for resource calculation
|
|
37
|
+
* @returns Resource limits for parallel execution
|
|
38
|
+
*/
|
|
39
|
+
export declare function calculateResources(reservePercent?: number, options?: {
|
|
40
|
+
measureDisk?: boolean;
|
|
41
|
+
}): Promise<ResourceLimits>;
|
|
42
|
+
/**
|
|
43
|
+
* Synchronous version that skips disk measurement (for quick startup).
|
|
44
|
+
*
|
|
45
|
+
* @param reservePercent - Percentage of resources to reserve (default: 0.75 for 75%)
|
|
46
|
+
* @returns Resource limits for parallel execution (with estimated I/O)
|
|
47
|
+
*/
|
|
48
|
+
export declare function calculateResourcesSync(reservePercent?: number): ResourceLimits;
|
|
49
|
+
//# sourceMappingURL=resource-calculator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-calculator.d.ts","sourceRoot":"","sources":["../../src/executor/resource-calculator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAOH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,eAAe,EAAE,MAAM,CAAC;CACxB;AA6ED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACvC,cAAc,SAAO,EACrB,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAO,GACrC,OAAO,CAAC,cAAc,CAAC,CAqBzB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,cAAc,SAAO,GAAG,cAAc,CAgB5E"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resource Calculator
|
|
3
|
+
*
|
|
4
|
+
* Automatically calculates optimal resource limits for parallel execution
|
|
5
|
+
* using the "75% rule" - reserves 75% of available resources for workers,
|
|
6
|
+
* leaving 25% for system stability and other processes.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - CPU-based worker count (75% of available cores)
|
|
10
|
+
* - Memory per worker calculation (total memory / worker count)
|
|
11
|
+
* - Dynamic disk I/O ceiling measurement (detects throughput plateau)
|
|
12
|
+
* - Caching to avoid repeated measurements
|
|
13
|
+
*
|
|
14
|
+
* Disk I/O Measurement Algorithm:
|
|
15
|
+
* 1. Test concurrent write+read operations at increasing levels (1, 6, 11, 16, ...)
|
|
16
|
+
* 2. Measure throughput (MB/s) for each concurrency level
|
|
17
|
+
* 3. Detect when throughput plateaus (<5% improvement)
|
|
18
|
+
* 4. Return 75% of the detected ceiling
|
|
19
|
+
* 5. Cache result to avoid re-measuring
|
|
20
|
+
*/
|
|
21
|
+
import { cpus, totalmem } from "node:os";
|
|
22
|
+
import { mkdtemp, readFile, writeFile, unlink } from "node:fs/promises";
|
|
23
|
+
import { join } from "node:path";
|
|
24
|
+
import { tmpdir } from "node:os";
|
|
25
|
+
/**
|
|
26
|
+
* Measure disk I/O ceiling by testing throughput at increasing concurrency levels.
|
|
27
|
+
* Returns the concurrency level where throughput stops improving (the ceiling).
|
|
28
|
+
*
|
|
29
|
+
* @param sampleSizeMb - Size of test data in MB (default: 10)
|
|
30
|
+
* @param maxConcurrency - Maximum concurrency to test (default: 100)
|
|
31
|
+
* @param timeoutMs - Timeout per test in milliseconds (default: 5000)
|
|
32
|
+
* @returns The detected concurrency ceiling
|
|
33
|
+
*/
|
|
34
|
+
async function measureDiskIoCeiling(sampleSizeMb = 10, maxConcurrency = 100, timeoutMs = 5000) {
|
|
35
|
+
const testData = Buffer.alloc(sampleSizeMb * 1024 * 1024, "x");
|
|
36
|
+
// Test at increasing concurrency levels
|
|
37
|
+
let lastThroughput = 0;
|
|
38
|
+
let ceiling = 10; // Default fallback
|
|
39
|
+
for (let concurrency = 1; concurrency <= maxConcurrency; concurrency += 5) {
|
|
40
|
+
const tempDir = await mkdtemp(join(tmpdir(), "io-test-"));
|
|
41
|
+
const startTime = performance.now();
|
|
42
|
+
try {
|
|
43
|
+
// Run concurrent write+read operations
|
|
44
|
+
const operations = Array.from({ length: concurrency }, async () => {
|
|
45
|
+
const filePath = join(tempDir, `test-${Math.random().toString(36).slice(2)}.dat`);
|
|
46
|
+
await writeFile(filePath, testData);
|
|
47
|
+
await readFile(filePath);
|
|
48
|
+
return filePath;
|
|
49
|
+
});
|
|
50
|
+
await Promise.race([
|
|
51
|
+
Promise.all(operations),
|
|
52
|
+
new Promise((_resolve, reject) => setTimeout(() => {
|
|
53
|
+
reject(new Error("timeout"));
|
|
54
|
+
}, timeoutMs)),
|
|
55
|
+
]);
|
|
56
|
+
const elapsedMs = performance.now() - startTime;
|
|
57
|
+
const throughput = (concurrency * sampleSizeMb) / (elapsedMs / 1000);
|
|
58
|
+
// Check if we've hit the ceiling (throughput not improving)
|
|
59
|
+
if (throughput > lastThroughput * 1.05) {
|
|
60
|
+
// Still improving
|
|
61
|
+
lastThroughput = throughput;
|
|
62
|
+
ceiling = concurrency;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// Throughput plateaued - we found the ceiling
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// Timeout or error - previous level was the ceiling
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
// Cleanup
|
|
75
|
+
try {
|
|
76
|
+
const { readdir } = await import("node:fs/promises");
|
|
77
|
+
const files = await readdir(tempDir);
|
|
78
|
+
await Promise.all(files.map((f) => unlink(join(tempDir, f))));
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// Ignore cleanup errors
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return ceiling;
|
|
86
|
+
}
|
|
87
|
+
/** Cached disk I/O ceiling measurement */
|
|
88
|
+
let cachedCeiling = null;
|
|
89
|
+
/**
|
|
90
|
+
* Calculate resource limits using the 75% rule.
|
|
91
|
+
*
|
|
92
|
+
* @param reservePercent - Percentage of resources to reserve (default: 0.75 for 75%)
|
|
93
|
+
* @param options - Options for resource calculation
|
|
94
|
+
* @returns Resource limits for parallel execution
|
|
95
|
+
*/
|
|
96
|
+
export async function calculateResources(reservePercent = 0.75, options = {}) {
|
|
97
|
+
const cpuCount = cpus().length;
|
|
98
|
+
const totalMemory = totalmem();
|
|
99
|
+
// Clamp reservePercent to [0, 1] range
|
|
100
|
+
const clampedReserve = Math.max(0, Math.min(1, reservePercent));
|
|
101
|
+
const maxWorkers = Math.floor(cpuCount * clampedReserve);
|
|
102
|
+
// Avoid division by zero when maxWorkers is 0
|
|
103
|
+
const maxMemoryMb = maxWorkers > 0 ? Math.floor((totalMemory * clampedReserve) / maxWorkers / (1024 * 1024)) : 0;
|
|
104
|
+
// Measure disk I/O ceiling once, then cache
|
|
105
|
+
let maxConcurrentIo = Math.floor(100 * clampedReserve);
|
|
106
|
+
if (options.measureDisk !== false && maxWorkers > 0) {
|
|
107
|
+
cachedCeiling ??= await measureDiskIoCeiling();
|
|
108
|
+
maxConcurrentIo = Math.floor(cachedCeiling * clampedReserve);
|
|
109
|
+
}
|
|
110
|
+
return { maxWorkers, maxMemoryMb, maxConcurrentIo };
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Synchronous version that skips disk measurement (for quick startup).
|
|
114
|
+
*
|
|
115
|
+
* @param reservePercent - Percentage of resources to reserve (default: 0.75 for 75%)
|
|
116
|
+
* @returns Resource limits for parallel execution (with estimated I/O)
|
|
117
|
+
*/
|
|
118
|
+
export function calculateResourcesSync(reservePercent = 0.75) {
|
|
119
|
+
const cpuCount = cpus().length;
|
|
120
|
+
const totalMemory = totalmem();
|
|
121
|
+
// Clamp reservePercent to [0, 1] range
|
|
122
|
+
const clampedReserve = Math.max(0, Math.min(1, reservePercent));
|
|
123
|
+
const maxWorkers = Math.floor(cpuCount * clampedReserve);
|
|
124
|
+
// Avoid division by zero when maxWorkers is 0
|
|
125
|
+
const maxMemoryMb = maxWorkers > 0 ? Math.floor((totalMemory * clampedReserve) / maxWorkers / (1024 * 1024)) : 0;
|
|
126
|
+
const maxConcurrentIo = Math.floor(100 * clampedReserve);
|
|
127
|
+
return { maxWorkers, maxMemoryMb, maxConcurrentIo };
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=resource-calculator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-calculator.js","sourceRoot":"","sources":["../../src/executor/resource-calculator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-id.d.ts","sourceRoot":"","sources":["../../src/executor/run-id.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IAEd,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAC;IAEf,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,aAAa,GAAI,QAAQ,WAAW,KAAG,MAInD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,
|
|
1
|
+
{"version":3,"file":"run-id.d.ts","sourceRoot":"","sources":["../../src/executor/run-id.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IAEd,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAC;IAEf,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,aAAa,GAAI,QAAQ,WAAW,KAAG,MAInD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,MAUpE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,EAAE,QAAQ,WAAW,KAAG,OACnC,CAAC;AAEjC;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,KAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAM1E,CAAC"}
|
package/dist/executor/run-id.js
CHANGED
|
@@ -38,7 +38,14 @@ export const generateRunId = (inputs) => {
|
|
|
38
38
|
* @returns 8-character hex string
|
|
39
39
|
*/
|
|
40
40
|
export const generateConfigHash = (config) => {
|
|
41
|
-
|
|
41
|
+
// Sort keys for consistent ordering, then stringify without replacer
|
|
42
|
+
// (using replacer array would filter nested properties)
|
|
43
|
+
const sortedKeys = Object.keys(config).sort();
|
|
44
|
+
const sortedObj = {};
|
|
45
|
+
for (const key of sortedKeys) {
|
|
46
|
+
sortedObj[key] = config[key];
|
|
47
|
+
}
|
|
48
|
+
const canonical = JSON.stringify(sortedObj);
|
|
42
49
|
return createHash("sha256").update(canonical).digest("hex").slice(0, 8);
|
|
43
50
|
};
|
|
44
51
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-id.js","sourceRoot":"","sources":["../../src/executor/run-id.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAsBzC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAmB,EAAU,EAAE;IAC5D,mCAAmC;IACnC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrE,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC1E,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAA+B,EAAU,EAAE;IAC7E,MAAM,
|
|
1
|
+
{"version":3,"file":"run-id.js","sourceRoot":"","sources":["../../src/executor/run-id.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAsBzC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAmB,EAAU,EAAE;IAC5D,mCAAmC;IACnC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrE,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC1E,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAA+B,EAAU,EAAE;IAC7E,qEAAqE;IACrE,wDAAwD;IACxD,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9C,MAAM,SAAS,GAA4B,EAAE,CAAC;IAC9C,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC9B,SAAS,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACzE,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAa,EAAE,MAAmB,EAAW,EAAE,CAC5E,KAAK,KAAK,aAAa,CAAC,MAAM,CAAC,CAAC;AAEjC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAa,EAAsC,EAAE;IAC/E,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzC,OAAO;QACN,KAAK,EAAE,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE;QACnC,MAAM,EAAE,KAAK,CAAC,MAAM;KACpB,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-entry.d.ts","sourceRoot":"","sources":["../../src/executor/worker-entry.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"worker-entry.d.ts","sourceRoot":"","sources":["../../src/executor/worker-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|