mirror of
https://github.com/stablyai/orca.git
synced 2026-10-01 08:01:56 +00:00
Resolve Resource Manager Space scan ready state before commit (#3200)
* Resolve resource space scan ready state before commit * Avoid render-time ref writes for space scan ready state Co-authored-by: Orca <help@stably.ai> --------- Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com> Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
@@ -61,6 +61,10 @@ import {
|
||||
getResourceUsageRuntimePaneTitlesByTabId,
|
||||
getResourceUsageTabsByWorktree
|
||||
} from './resource-usage-open-slices'
|
||||
import {
|
||||
resolveResourceUsageSpaceScanReady,
|
||||
type ResourceUsageSpaceScanSnapshot
|
||||
} from './resource-usage-space-scan-ready'
|
||||
|
||||
const POLL_MS = 2_000
|
||||
const SESSIONS_POLL_MS = 10_000
|
||||
@@ -670,7 +674,13 @@ export function ResourceUsageStatusSegment({
|
||||
const [sessionsError, setSessionsError] = useState(false)
|
||||
const [killConfirm, setKillConfirm] = useState<UnifiedSessionRow | null>(null)
|
||||
const [killing, setKilling] = useState(false)
|
||||
const [spaceScanReady, setSpaceScanReady] = useState(false)
|
||||
const [spaceScanSnapshot, setSpaceScanSnapshot] = useState<ResourceUsageSpaceScanSnapshot>(
|
||||
() => ({
|
||||
ready: false,
|
||||
previousScanning: workspaceSpaceScanning,
|
||||
lastSeenScannedAt: workspaceSpaceScannedAt
|
||||
})
|
||||
)
|
||||
// Why: tab titles can update on terminal keystrokes. The resource popover's
|
||||
// merged tree needs them only while open, so closed status-bar badges should
|
||||
// not subscribe to those high-churn maps.
|
||||
@@ -684,8 +694,6 @@ export function ResourceUsageStatusSegment({
|
||||
const tabsByWorktree = useAppStore((s) =>
|
||||
getResourceUsageTabsByWorktree(s, open, runtimeEnvironmentActive)
|
||||
)
|
||||
const previousSpaceScanningRef = useRef(workspaceSpaceScanning)
|
||||
const lastSeenSpaceScanAtRef = useRef<number | null>(workspaceSpaceScannedAt)
|
||||
// Why: this segment only understands the local Electron PTY/resource daemon.
|
||||
// While a runtime server is active, hiding local samples avoids showing or
|
||||
// killing sessions from the wrong machine.
|
||||
@@ -754,37 +762,24 @@ export function ResourceUsageStatusSegment({
|
||||
|
||||
// Why: Space scans can finish after the user backs out of the full page or
|
||||
// closes this popover; the status-bar trigger becomes the handoff point.
|
||||
useEffect(() => {
|
||||
if (runtimeEnvironmentActive) {
|
||||
setSpaceScanReady(false)
|
||||
previousSpaceScanningRef.current = false
|
||||
return
|
||||
}
|
||||
const scannedAt = workspaceSpaceScannedAt
|
||||
const wasScanning = previousSpaceScanningRef.current
|
||||
const scanCompleted =
|
||||
wasScanning &&
|
||||
!workspaceSpaceScanning &&
|
||||
scannedAt !== null &&
|
||||
scannedAt !== lastSeenSpaceScanAtRef.current
|
||||
|
||||
if (scanCompleted) {
|
||||
lastSeenSpaceScanAtRef.current = scannedAt
|
||||
setSpaceScanReady(!open && activeView !== 'space')
|
||||
} else if (spaceScanReady && (open || activeView === 'space')) {
|
||||
setSpaceScanReady(false)
|
||||
lastSeenSpaceScanAtRef.current = scannedAt
|
||||
}
|
||||
|
||||
previousSpaceScanningRef.current = workspaceSpaceScanning
|
||||
}, [
|
||||
activeView,
|
||||
open,
|
||||
const nextSpaceScanSnapshot = resolveResourceUsageSpaceScanReady({
|
||||
snapshot: spaceScanSnapshot,
|
||||
runtimeEnvironmentActive,
|
||||
spaceScanReady,
|
||||
workspaceSpaceScannedAt,
|
||||
workspaceSpaceScanning
|
||||
])
|
||||
open,
|
||||
activeView,
|
||||
scannedAt: workspaceSpaceScannedAt,
|
||||
scanning: workspaceSpaceScanning
|
||||
})
|
||||
if (
|
||||
nextSpaceScanSnapshot.ready !== spaceScanSnapshot.ready ||
|
||||
nextSpaceScanSnapshot.previousScanning !== spaceScanSnapshot.previousScanning ||
|
||||
nextSpaceScanSnapshot.lastSeenScannedAt !== spaceScanSnapshot.lastSeenScannedAt
|
||||
) {
|
||||
// Why: keep the scan transition render-time without mutating refs during
|
||||
// render; React can safely retry this guarded state update before commit.
|
||||
setSpaceScanSnapshot(nextSpaceScanSnapshot)
|
||||
}
|
||||
const spaceScanReady = nextSpaceScanSnapshot.ready
|
||||
|
||||
// Poll memory + sessions when popover is open. Sessions also poll in the
|
||||
// background at a slower rate so the badge count stays reasonably fresh
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import {
|
||||
resolveResourceUsageSpaceScanReady,
|
||||
type ResourceUsageSpaceScanSnapshot
|
||||
} from './resource-usage-space-scan-ready'
|
||||
|
||||
const baseSnapshot: ResourceUsageSpaceScanSnapshot = {
|
||||
ready: false,
|
||||
previousScanning: false,
|
||||
lastSeenScannedAt: null
|
||||
}
|
||||
|
||||
describe('resolveResourceUsageSpaceScanReady', () => {
|
||||
it('marks Space results ready when a scan finishes away from the resource popover and Space page', () => {
|
||||
expect(
|
||||
resolveResourceUsageSpaceScanReady({
|
||||
snapshot: { ...baseSnapshot, previousScanning: true },
|
||||
runtimeEnvironmentActive: false,
|
||||
open: false,
|
||||
activeView: 'terminal',
|
||||
scannedAt: 100,
|
||||
scanning: false
|
||||
})
|
||||
).toEqual({
|
||||
ready: true,
|
||||
previousScanning: false,
|
||||
lastSeenScannedAt: 100
|
||||
})
|
||||
})
|
||||
|
||||
it('does not show the ready handoff when results finish while already visible', () => {
|
||||
expect(
|
||||
resolveResourceUsageSpaceScanReady({
|
||||
snapshot: { ...baseSnapshot, previousScanning: true },
|
||||
runtimeEnvironmentActive: false,
|
||||
open: true,
|
||||
activeView: 'terminal',
|
||||
scannedAt: 100,
|
||||
scanning: false
|
||||
})
|
||||
).toEqual({
|
||||
ready: false,
|
||||
previousScanning: false,
|
||||
lastSeenScannedAt: 100
|
||||
})
|
||||
|
||||
expect(
|
||||
resolveResourceUsageSpaceScanReady({
|
||||
snapshot: { ...baseSnapshot, previousScanning: true },
|
||||
runtimeEnvironmentActive: false,
|
||||
open: false,
|
||||
activeView: 'space',
|
||||
scannedAt: 100,
|
||||
scanning: false
|
||||
}).ready
|
||||
).toBe(false)
|
||||
})
|
||||
|
||||
it('clears the handoff once the popover or Space page is opened', () => {
|
||||
const readySnapshot = {
|
||||
ready: true,
|
||||
previousScanning: false,
|
||||
lastSeenScannedAt: 100
|
||||
}
|
||||
|
||||
expect(
|
||||
resolveResourceUsageSpaceScanReady({
|
||||
snapshot: readySnapshot,
|
||||
runtimeEnvironmentActive: false,
|
||||
open: true,
|
||||
activeView: 'terminal',
|
||||
scannedAt: 100,
|
||||
scanning: false
|
||||
})
|
||||
).toEqual({
|
||||
ready: false,
|
||||
previousScanning: false,
|
||||
lastSeenScannedAt: 100
|
||||
})
|
||||
|
||||
expect(
|
||||
resolveResourceUsageSpaceScanReady({
|
||||
snapshot: readySnapshot,
|
||||
runtimeEnvironmentActive: false,
|
||||
open: false,
|
||||
activeView: 'space',
|
||||
scannedAt: 100,
|
||||
scanning: false
|
||||
}).ready
|
||||
).toBe(false)
|
||||
})
|
||||
|
||||
it('does not announce the same scan completion twice', () => {
|
||||
const result = resolveResourceUsageSpaceScanReady({
|
||||
snapshot: {
|
||||
ready: false,
|
||||
previousScanning: true,
|
||||
lastSeenScannedAt: 100
|
||||
},
|
||||
runtimeEnvironmentActive: false,
|
||||
open: false,
|
||||
activeView: 'terminal',
|
||||
scannedAt: 100,
|
||||
scanning: false
|
||||
})
|
||||
|
||||
expect(result.ready).toBe(false)
|
||||
expect(result.lastSeenScannedAt).toBe(100)
|
||||
})
|
||||
|
||||
it('hides local Space scan handoffs while a remote runtime is active', () => {
|
||||
expect(
|
||||
resolveResourceUsageSpaceScanReady({
|
||||
snapshot: {
|
||||
ready: true,
|
||||
previousScanning: true,
|
||||
lastSeenScannedAt: 100
|
||||
},
|
||||
runtimeEnvironmentActive: true,
|
||||
open: false,
|
||||
activeView: 'terminal',
|
||||
scannedAt: 200,
|
||||
scanning: true
|
||||
})
|
||||
).toEqual({
|
||||
ready: false,
|
||||
previousScanning: false,
|
||||
lastSeenScannedAt: 100
|
||||
})
|
||||
})
|
||||
|
||||
it('tracks scanning starts without changing readiness', () => {
|
||||
expect(
|
||||
resolveResourceUsageSpaceScanReady({
|
||||
snapshot: baseSnapshot,
|
||||
runtimeEnvironmentActive: false,
|
||||
open: false,
|
||||
activeView: 'terminal',
|
||||
scannedAt: null,
|
||||
scanning: true
|
||||
})
|
||||
).toEqual({
|
||||
ready: false,
|
||||
previousScanning: true,
|
||||
lastSeenScannedAt: null
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,60 @@
|
||||
export type ResourceUsageSpaceScanSnapshot = {
|
||||
ready: boolean
|
||||
previousScanning: boolean
|
||||
lastSeenScannedAt: number | null
|
||||
}
|
||||
|
||||
export function resolveResourceUsageSpaceScanReady({
|
||||
snapshot,
|
||||
runtimeEnvironmentActive,
|
||||
open,
|
||||
activeView,
|
||||
scannedAt,
|
||||
scanning
|
||||
}: {
|
||||
snapshot: ResourceUsageSpaceScanSnapshot
|
||||
runtimeEnvironmentActive: boolean
|
||||
open: boolean
|
||||
activeView: string
|
||||
scannedAt: number | null
|
||||
scanning: boolean
|
||||
}): ResourceUsageSpaceScanSnapshot {
|
||||
if (runtimeEnvironmentActive) {
|
||||
return {
|
||||
ready: false,
|
||||
previousScanning: false,
|
||||
lastSeenScannedAt: snapshot.lastSeenScannedAt
|
||||
}
|
||||
}
|
||||
|
||||
const scanCompleted =
|
||||
snapshot.previousScanning &&
|
||||
!scanning &&
|
||||
scannedAt !== null &&
|
||||
scannedAt !== snapshot.lastSeenScannedAt
|
||||
|
||||
if (scanCompleted) {
|
||||
return {
|
||||
ready: !open && activeView !== 'space',
|
||||
previousScanning: scanning,
|
||||
lastSeenScannedAt: scannedAt
|
||||
}
|
||||
}
|
||||
|
||||
if (snapshot.ready && (open || activeView === 'space')) {
|
||||
return {
|
||||
ready: false,
|
||||
previousScanning: scanning,
|
||||
lastSeenScannedAt: scannedAt
|
||||
}
|
||||
}
|
||||
|
||||
if (snapshot.previousScanning !== scanning) {
|
||||
return {
|
||||
...snapshot,
|
||||
previousScanning: scanning
|
||||
}
|
||||
}
|
||||
|
||||
return snapshot
|
||||
}
|
||||
Reference in New Issue
Block a user