fix(#2855): tmux health check fails across module instances in same process
The server-health module used module-level state for inProcessServerRunning, which doesn't survive when Bun loads separate module instances in the same process. Fix: use globalThis with Symbol.for key so the flag is truly process-global. - server-health.ts: replace module-level boolean with globalThis[Symbol.for()] - export markServerRunningInProcess from tmux-utils barrel - test: verify flag skips HTTP fetch, verify globalThis persistence
This commit is contained in:
@@ -3,6 +3,7 @@ import {
|
||||
isInsideTmux,
|
||||
isServerRunning,
|
||||
resetServerCheck,
|
||||
markServerRunningInProcess,
|
||||
spawnTmuxPane,
|
||||
closeTmuxPane,
|
||||
applyLayout,
|
||||
@@ -165,6 +166,46 @@ describe("resetServerCheck", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("markServerRunningInProcess", () => {
|
||||
const originalFetch = globalThis.fetch
|
||||
const SERVER_RUNNING_KEY = Symbol.for("oh-my-opencode:server-running-in-process")
|
||||
|
||||
beforeEach(() => {
|
||||
resetServerCheck()
|
||||
delete (globalThis as Record<symbol, boolean>)[SERVER_RUNNING_KEY]
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
globalThis.fetch = originalFetch
|
||||
delete (globalThis as Record<symbol, boolean>)[SERVER_RUNNING_KEY]
|
||||
})
|
||||
|
||||
test("skips HTTP fetch when marked as running in-process", async () => {
|
||||
// given
|
||||
const fetchMock = mock(async () => ({ ok: true })) as any
|
||||
globalThis.fetch = fetchMock
|
||||
markServerRunningInProcess()
|
||||
|
||||
// when
|
||||
const result = await isServerRunning("http://localhost:4096")
|
||||
|
||||
// then
|
||||
expect(result).toBe(true)
|
||||
expect(fetchMock.mock.calls.length).toBe(0)
|
||||
})
|
||||
|
||||
test("uses globalThis so flag survives across module instances", () => {
|
||||
// given
|
||||
markServerRunningInProcess()
|
||||
|
||||
// when
|
||||
const flag = (globalThis as Record<symbol, boolean>)[SERVER_RUNNING_KEY]
|
||||
|
||||
// then
|
||||
expect(flag).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe("tmux pane functions", () => {
|
||||
test("spawnTmuxPane is exported as function", async () => {
|
||||
// given, #when
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export { isInsideTmux, getCurrentPaneId } from "./tmux-utils/environment"
|
||||
export type { SplitDirection } from "./tmux-utils/environment"
|
||||
|
||||
export { isServerRunning, resetServerCheck } from "./tmux-utils/server-health"
|
||||
export { isServerRunning, resetServerCheck, markServerRunningInProcess } from "./tmux-utils/server-health"
|
||||
|
||||
export { getPaneDimensions } from "./tmux-utils/pane-dimensions"
|
||||
export type { PaneDimensions } from "./tmux-utils/pane-dimensions"
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
let serverAvailable: boolean | null = null
|
||||
let serverCheckUrl: string | null = null
|
||||
let inProcessServerRunning = false
|
||||
|
||||
const SERVER_RUNNING_KEY = Symbol.for("oh-my-opencode:server-running-in-process")
|
||||
|
||||
function delay(milliseconds: number): Promise<void> {
|
||||
return new Promise((resolve) => setTimeout(resolve, milliseconds))
|
||||
}
|
||||
|
||||
export function markServerRunningInProcess(): void {
|
||||
inProcessServerRunning = true
|
||||
;(globalThis as Record<symbol, boolean>)[SERVER_RUNNING_KEY] = true
|
||||
}
|
||||
|
||||
function isMarkedRunningInProcess(): boolean {
|
||||
return (globalThis as Record<symbol, boolean>)[SERVER_RUNNING_KEY] === true
|
||||
}
|
||||
|
||||
export async function isServerRunning(serverUrl: string): Promise<boolean> {
|
||||
if (inProcessServerRunning) {
|
||||
if (isMarkedRunningInProcess()) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user