mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 10:27:33 +00:00
perf(sidebar): stop re-inspecting the setup-script prompt on every worktree revisit (#29514)
Refs #26785
This commit is contained in:
@@ -5,7 +5,10 @@ import { createRoot, type Root } from 'react-dom/client'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { useAppStore } from '@/store'
|
||||
import type { Repo } from '../../../../shared/repo-types'
|
||||
import { useSetupScriptPromptRevalidation } from './useSetupScriptPromptRevalidation'
|
||||
import {
|
||||
SETUP_PROMPT_REVISIT_REVALIDATION_INTERVAL_MS,
|
||||
useSetupScriptPromptRevalidation
|
||||
} from './useSetupScriptPromptRevalidation'
|
||||
import type { SetupScriptPromptState } from './setup-script-prompt-render-state'
|
||||
import { getRepoHostIdentityForParts } from '@/store/slices/repo-host-identity'
|
||||
|
||||
@@ -261,6 +264,35 @@ describe('useSetupScriptPromptRevalidation', () => {
|
||||
expect(requestRevalidation).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('re-inspects each worktree once on first activation, not on every revisit', async () => {
|
||||
const now = vi.spyOn(Date, 'now').mockReturnValue(1_000_000)
|
||||
const requestRevalidation = vi.fn()
|
||||
await render({
|
||||
activeRepo: GIT_REPO,
|
||||
isDismissed: false,
|
||||
sidebarOpen: true,
|
||||
promptState: missingSetup('repo-1'),
|
||||
requestRevalidation
|
||||
})
|
||||
|
||||
// Before: every one of these 20 switches cost a hooksCheck + setupScriptImports pair.
|
||||
for (let round = 0; round < 10; round += 1) {
|
||||
await setActiveWorktree('worktree-2')
|
||||
await setActiveWorktree('worktree-1')
|
||||
}
|
||||
expect(requestRevalidation).toHaveBeenCalledTimes(1)
|
||||
|
||||
await setActiveWorktree('worktree-3')
|
||||
expect(requestRevalidation).toHaveBeenCalledTimes(2)
|
||||
|
||||
now.mockReturnValue(1_000_000 + SETUP_PROMPT_REVISIT_REVALIDATION_INTERVAL_MS)
|
||||
await setActiveWorktree('worktree-1')
|
||||
expect(requestRevalidation).toHaveBeenCalledTimes(3)
|
||||
await setActiveWorktree('worktree-2')
|
||||
expect(requestRevalidation).toHaveBeenCalledTimes(3)
|
||||
now.mockRestore()
|
||||
})
|
||||
|
||||
it('re-inspects when the repo runtime reconnects', async () => {
|
||||
const requestRevalidation = vi.fn()
|
||||
await setRuntimeConnectionGeneration(1)
|
||||
|
||||
@@ -6,6 +6,9 @@ import { getRepoHostIdentity } from '@/store/slices/repo-host-identity'
|
||||
import { getRepoExecutionHostId, parseExecutionHostId } from '../../../../shared/execution-host'
|
||||
import type { SetupScriptPromptState } from './setup-script-prompt-render-state'
|
||||
|
||||
/** Revisiting an already-activated worktree re-inspects at most this often. */
|
||||
export const SETUP_PROMPT_REVISIT_REVALIDATION_INTERVAL_MS = 30_000
|
||||
|
||||
/**
|
||||
* Re-runs the setup-script prompt inspection when a shared `orca.yaml` setup hook
|
||||
* can have become effective outside SetupScriptPromptCard's reactive inputs, so a
|
||||
@@ -72,6 +75,12 @@ export function useSetupScriptPromptRevalidation(input: {
|
||||
// card nulls it for the whole inspection round trip). Remember them instead of
|
||||
// dropping them, then replay once a revalidatable result exists.
|
||||
const pendingRevalidationRef = useRef(false)
|
||||
// Why: a worktree's first activation is when its creation-time setup hook can have landed.
|
||||
// Re-inspecting on every revisit cost two host round trips per click on remote repos (#26785).
|
||||
const activatedWorktreeIdsRef = useRef(
|
||||
new Set<string>(activeWorktreeId ? [activeWorktreeId] : [])
|
||||
)
|
||||
const lastActivationRevalidationAtRef = useRef(Number.NEGATIVE_INFINITY)
|
||||
|
||||
useEffect(() => {
|
||||
const worktreeChanged = previousWorktreeIdRef.current !== activeWorktreeId
|
||||
@@ -85,8 +94,21 @@ export function useSetupScriptPromptRevalidation(input: {
|
||||
if (hostChanged) {
|
||||
// A repo/host switch re-runs the card's own inspection, so no extra pass is owed.
|
||||
pendingRevalidationRef.current = false
|
||||
} else if (worktreeChanged || reconnected) {
|
||||
} else if (reconnected) {
|
||||
pendingRevalidationRef.current = true
|
||||
} else if (worktreeChanged) {
|
||||
const firstActivation =
|
||||
activeWorktreeId !== null && !activatedWorktreeIdsRef.current.has(activeWorktreeId)
|
||||
if (activeWorktreeId !== null) {
|
||||
activatedWorktreeIdsRef.current.add(activeWorktreeId)
|
||||
}
|
||||
if (
|
||||
firstActivation ||
|
||||
Date.now() - lastActivationRevalidationAtRef.current >=
|
||||
SETUP_PROMPT_REVISIT_REVALIDATION_INTERVAL_MS
|
||||
) {
|
||||
pendingRevalidationRef.current = true
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -100,6 +122,7 @@ export function useSetupScriptPromptRevalidation(input: {
|
||||
return
|
||||
}
|
||||
pendingRevalidationRef.current = false
|
||||
lastActivationRevalidationAtRef.current = Date.now()
|
||||
requestRevalidation()
|
||||
}, [
|
||||
activeRepo,
|
||||
|
||||
Reference in New Issue
Block a user