mirror of
https://github.com/stablyai/orca.git
synced 2026-10-18 16:03:17 +00:00
perf(checks-panel): gate the terminal-cwd poll on window visibility
The Checks panel polls window.api.pty.getCwd every 4s to follow the active terminal's cwd. It was gated only on panel visibility (isPanelVisible), not window visibility — so a hidden or minimized window kept spawning lsof on macOS every 4s (the 4s cadence exceeds getCwd's 1.5s per-pid cache TTL, so every tick is a guaranteed miss and a fresh subprocess). Swap the raw window.setInterval for installWindowVisibilityInterval — the shared helper every sibling timer already uses — which pauses while the window is hidden and runs an immediate refresh on becoming visible so a cd made while hidden is picked up on return. A visible-but-unfocused window (second monitor) keeps polling, matching prior behavior. Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
@@ -129,6 +129,36 @@ describe('useChecksPanelTerminalWorktree', () => {
|
||||
expect(latest?.worktree).toBe(parentWorktree)
|
||||
})
|
||||
|
||||
it('does not spawn getCwd while the window is hidden, then refreshes on becoming visible', async () => {
|
||||
getCwdMock.mockResolvedValue(`${CHILD_PATH}/src`)
|
||||
const setVisibility = (state: 'visible' | 'hidden'): void => {
|
||||
Object.defineProperty(document, 'visibilityState', {
|
||||
configurable: true,
|
||||
get: () => state
|
||||
})
|
||||
}
|
||||
setVisibility('hidden')
|
||||
try {
|
||||
await renderHook(parentWorktree)
|
||||
await flushMicrotasks()
|
||||
// Hidden window: no lsof-backed cwd probe at all.
|
||||
expect(getCwdMock).not.toHaveBeenCalled()
|
||||
expect(latest?.worktree).toBe(parentWorktree)
|
||||
|
||||
setVisibility('visible')
|
||||
await act(async () => {
|
||||
document.dispatchEvent(new Event('visibilitychange'))
|
||||
})
|
||||
await flushMicrotasks()
|
||||
// Becoming visible runs an immediate refresh (a `cd` made while hidden
|
||||
// is picked up promptly on return).
|
||||
expect(getCwdMock).toHaveBeenCalledWith('pty-1')
|
||||
expect(latest?.worktree).toBe(childWorktree)
|
||||
} finally {
|
||||
setVisibility('visible')
|
||||
}
|
||||
})
|
||||
|
||||
it('keeps the default worktree when the cwd is outside every worktree', async () => {
|
||||
getCwdMock.mockResolvedValue('/tmp/scratch')
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import { useAppStore } from '@/store'
|
||||
import { installWindowVisibilityInterval } from '@/lib/window-visibility-interval'
|
||||
import { useAllWorktrees, useRepoMap } from '@/store/selectors'
|
||||
import { isRemoteRuntimePtyId } from '@/runtime/runtime-terminal-inspection'
|
||||
import { parseAppSshPtyId } from '../../../../shared/ssh-pty-id'
|
||||
@@ -31,7 +32,8 @@ type ChecksPanelTerminalWorktree = {
|
||||
* the *remote* shell's OSC 7 path, which must not resolve a local worktree.
|
||||
* getCwd reads the local shell pid, so it is correct for that case. Remote
|
||||
* runtime PTYs are skipped (their cwd lives on the relay host). Polling is
|
||||
* gated on panel visibility, so a hidden panel does no background work and the
|
||||
* gated on both panel visibility and window visibility, so a hidden panel or a
|
||||
* hidden/minimized window does no background work (no `lsof` spawns) and the
|
||||
* caller's fallback worktree is used.
|
||||
*
|
||||
* Resolution is scoped to locally-executing worktrees: the cwd comes from a
|
||||
@@ -123,11 +125,18 @@ export function useChecksPanelTerminalWorktree(args: {
|
||||
}
|
||||
}
|
||||
|
||||
void refresh()
|
||||
const interval = window.setInterval(refresh, TERMINAL_CWD_POLL_MS)
|
||||
// Why: getCwd shells out to `lsof` on macOS every tick (poll cadence >
|
||||
// the 1.5s per-pid cache TTL, so each tick is a guaranteed miss). Gate on
|
||||
// window visibility so a hidden/minimized window spawns no subprocesses;
|
||||
// the helper runs an immediate refresh on becoming visible so a `cd` made
|
||||
// while hidden is picked up promptly on return.
|
||||
const stopInterval = installWindowVisibilityInterval({
|
||||
run: () => void refresh(),
|
||||
intervalMs: TERMINAL_CWD_POLL_MS
|
||||
})
|
||||
return () => {
|
||||
disposed = true
|
||||
window.clearInterval(interval)
|
||||
stopInterval()
|
||||
}
|
||||
}, [activeTerminalPtyId, shouldPollCwd])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user