Skip to content

Commit ffb9782

Browse files
committed
merge(dev): pick up darwin worker OS-join settle
Take tip's darwin settle + isolate churn cap so this branch stays current with the storage-worker teardown fix line.
2 parents 649fdf9 + 58be730 commit ffb9782

2 files changed

Lines changed: 20 additions & 25 deletions

File tree

src/storage/worker-lifecycle.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,7 @@ let spawnCancelEpoch = 0;
5656
const WORKER_OS_JOIN_MS = 250;
5757

5858
function needsWorkerOsJoinSettle(): boolean {
59-
// Linux GHA also hit Bun 1.3.14 balanced-count segfaults under `--isolate`
60-
// after storage-worker teardown (ubuntu-latest exit 132).
61-
return process.platform === "win32" || process.platform === "darwin" || process.platform === "linux";
59+
return process.platform === "win32" || process.platform === "darwin";
6260
}
6361

6462
/** Invalidate spawn callbacks still waiting on the gate (reset / server drain). */

tests/storage-worker-teardown-isolate.test.ts

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@
88
*
99
* A second Bun 1.3.14 failure mode is a mid-file / post-suite segfault with a
1010
* *balanced* `workers_spawned === workers_terminated` count (exit 133 /
11-
* Trace/BPT on macOS Silicon). Churn caps and afterAll settle were not enough
12-
* under GHA load; running macOS CI *without* `--isolate` hung the suite past
13-
* the 20-minute job ceiling. Keep isolate everywhere, skip Worker-spawning
14-
* cases on darwin (platform-cap meta-test still runs), and keep OS-join settle
15-
* in `worker-lifecycle` plus drain+settle in `afterEach` for local isolate runs.
11+
* Trace/BPT on macOS Silicon). Churn caps alone were not enough under GHA load;
12+
* running macOS CI *without* `--isolate` hung past the 20-minute job ceiling.
13+
* Keep isolate everywhere, skip Worker-spawning cases on darwin (platform-cap
14+
* meta-test still runs), and keep OS-join settle in `worker-lifecycle`.
1615
*
1716
* These cases hammer the exact failure window: fire-and-forget terminate must
1817
* still be joinable by drain, and repeated spawn → reset cycles must leave the
@@ -41,20 +40,21 @@ let testDir = "";
4140
let previousHome: string | undefined;
4241

4342
/**
44-
* Bun 1.3.14: Worker spawn in this file still segfaults the isolate process
45-
* after green assertions (balanced counts) on macOS Silicon and ubuntu-latest
46-
* (exit 133 / 132). Skip the hammer cases there; win32 keeps full coverage.
43+
* Bun 1.3.14 macOS Silicon: Worker spawn in this file still segfaults the
44+
* isolate process after green assertions (balanced counts). Skip the hammer
45+
* cases on darwin; win32/linux keep full coverage.
4746
*/
48-
const skipIsolateWorkerSpawn =
49-
process.platform === "darwin" || process.platform === "linux";
47+
const skipDarwinWorkerSpawn = process.platform === "darwin";
5048

5149
/** Spawn/reset iterations for the heavy churn case — platform-stressed carefully. */
5250
function workerChurnCyclesForIsolate(): number {
5351
if (process.platform === "win32") return 8;
54-
// Two cycles still segfaulted Bun 1.3.14 on macOS Silicon and ubuntu-latest
55-
// under `--isolate` after a green suite (balanced worker counts). One cycle
56-
// keeps a real spawn/reset proof without the churn that trips the runtime.
57-
return 1;
52+
// Two cycles still segfaulted Bun 1.3.14 on macOS Silicon under `--isolate`
53+
// after a green suite (balanced worker counts, exit 133). One cycle keeps a
54+
// real spawn/reset proof without the churn that trips the runtime.
55+
if (process.platform === "darwin") return 1;
56+
// Linux: short loop — eight cycles segfaulted with balanced counts on ubuntu CI.
57+
return 2;
5858
}
5959

6060
function seedArchived(codexHome: string): void {
@@ -77,9 +77,6 @@ afterEach(async () => {
7777
await resetStorageCleanupPolicyJobForTestsAsync();
7878
setStorageCleanupPolicyJobTestHooks(null);
7979
await drainStorageWorkers();
80-
// Bun 1.3.14: balanced-count segfault can hit mid-file (before afterAll) on
81-
// macOS Silicon and ubuntu-latest. Brief settle — not a CI timeout bump.
82-
if (process.platform !== "win32") await Bun.sleep(250);
8380
if (previousHome === undefined) delete process.env.OPENCODEX_HOME;
8481
else process.env.OPENCODEX_HOME = previousHome;
8582
isolatedCodexHome?.restore();
@@ -90,7 +87,6 @@ afterEach(async () => {
9087

9188
afterAll(async () => {
9289
await drainStorageWorkers();
93-
if (process.platform !== "win32") await Bun.sleep(250);
9490
});
9591

9692
async function waitForLiveWorker(timeoutMs = 10_000): Promise<void> {
@@ -102,7 +98,7 @@ async function waitForLiveWorker(timeoutMs = 10_000): Promise<void> {
10298
throw new Error("no storage worker was ever spawned; this test would prove nothing");
10399
}
104100

105-
test.skipIf(skipIsolateWorkerSpawn)("drain joins a fire-and-forget terminate before the isolate boundary", async () => {
101+
test.skipIf(skipDarwinWorkerSpawn)("drain joins a fire-and-forget terminate before the isolate boundary", async () => {
106102
// Reproduces the old race: sync reset void-terminates (and used to deregister
107103
// immediately), then drain returned on an empty set while the thread exited.
108104
setStorageCleanupPolicyJobTestHooks({ blockMs: 800 });
@@ -120,7 +116,7 @@ test.skipIf(skipIsolateWorkerSpawn)("drain joins a fire-and-forget terminate bef
120116
expect(liveStorageWorkerCount()).toBe(0);
121117
}, { timeout: 30_000 });
122118

123-
test.skipIf(skipIsolateWorkerSpawn)("repeated Windows-style spawn/reset cycles leave no live workers", async () => {
119+
test.skipIf(skipDarwinWorkerSpawn)("repeated Windows-style spawn/reset cycles leave no live workers", async () => {
124120
const cycles = workerChurnCyclesForIsolate();
125121
for (let i = 0; i < cycles; i++) {
126122
// Fresh CODEX_HOME each cycle so a prior worker's SQLite handle cannot
@@ -144,10 +140,11 @@ test.skipIf(skipIsolateWorkerSpawn)("repeated Windows-style spawn/reset cycles l
144140
test("isolate worker churn stays platform-capped", () => {
145141
const cycles = workerChurnCyclesForIsolate();
146142
if (process.platform === "win32") expect(cycles).toBe(8);
147-
else expect(cycles).toBe(1);
143+
else if (process.platform === "darwin") expect(cycles).toBe(1);
144+
else expect(cycles).toBe(2);
148145
});
149146

150-
test.skipIf(skipIsolateWorkerSpawn)("terminateStorageWorker is joinable and idempotent across callers", async () => {
147+
test.skipIf(skipDarwinWorkerSpawn)("terminateStorageWorker is joinable and idempotent across callers", async () => {
151148
setStorageCleanupPolicyJobTestHooks({ blockMs: 500 });
152149
seedArchived(isolatedCodexHome!.path);
153150
const started = requestStorageCleanupPolicyRun({

0 commit comments

Comments
 (0)