Skip to content

Commit b5aac0c

Browse files
committed
perf(testcontainers): offset shard bins per package so heavy files don't stack on one shard
1 parent da87dc3 commit b5aac0c

1 file changed

Lines changed: 20 additions & 1 deletion

File tree

internal-packages/testcontainers/src/sequencer.cjs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,24 @@ function median(nums) {
5050
return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
5151
}
5252

53+
// Stable per-package offset (derived from the package dir) so each package's heaviest file - which
54+
// LPT always drops into bin 0 - maps to a DIFFERENT shard. Without it, a serial multi-package job
55+
// (`turbo --concurrency=1 --filter "@internal/*"`) stacks every package's heaviest file into shard 1.
56+
// It's a rotation of the bin->shard mapping, so coverage stays exact (each file runs once).
57+
function packageOffset(specs, count) {
58+
if (specs.length === 0) return 0;
59+
const rel = path.relative(REPO_ROOT, specs[0].moduleId);
60+
const key = rel.split(path.sep).slice(0, 2).join("/");
61+
// FNV-1a - spreads similar sibling package names (e.g. internal-packages/*) far better than a
62+
// simple polynomial hash mod count, which collided run-engine + schedule-engine onto one shard.
63+
let h = 2166136261;
64+
for (let i = 0; i < key.length; i++) {
65+
h ^= key.charCodeAt(i);
66+
h = Math.imul(h, 16777619);
67+
}
68+
return (h >>> 0) % count;
69+
}
70+
5371
/**
5472
* Duration-weighted interpretation of `--shard=i/N`. Instead of vitest's default file-count split,
5573
* this greedily bin-packs test files by recorded duration (test-timings.json at the repo root;
@@ -103,7 +121,8 @@ class DurationShardingSequencer {
103121
lightest.specs.push(spec);
104122
}
105123

106-
return bins[shard.index - 1].specs;
124+
const offset = packageOffset(specs, shard.count);
125+
return bins[(shard.index - 1 + offset) % shard.count].specs;
107126
}
108127
}
109128

0 commit comments

Comments
 (0)