mirror of
https://github.com/stablyai/orca.git
synced 2026-09-27 16:02:35 +00:00
fix: guard daemon session async state (#3543)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback, useState } from 'react'
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { LoaderCircle } from 'lucide-react'
|
||||
import { toast } from 'sonner'
|
||||
import { Button } from '../ui/button'
|
||||
@@ -39,6 +39,22 @@ export type DaemonActionsApi = {
|
||||
export function useDaemonActions(callbacks?: DaemonActionCallbacks): DaemonActionsApi {
|
||||
const [pending, setPending] = useState<PendingConfirm>(null)
|
||||
const [busyKind, setBusyKind] = useState<DaemonActionKind | null>(null)
|
||||
const mountedRef = useRef(true)
|
||||
|
||||
useEffect(() => {
|
||||
mountedRef.current = true
|
||||
return () => {
|
||||
mountedRef.current = false
|
||||
}
|
||||
}, [])
|
||||
|
||||
const clearPendingAction = useCallback((): void => {
|
||||
if (!mountedRef.current) {
|
||||
return
|
||||
}
|
||||
setBusyKind(null)
|
||||
setPending(null)
|
||||
}, [])
|
||||
|
||||
const runRestart = useCallback(async () => {
|
||||
setBusyKind('restart')
|
||||
@@ -54,11 +70,12 @@ export function useDaemonActions(callbacks?: DaemonActionCallbacks): DaemonActio
|
||||
description: err instanceof Error ? err.message : undefined
|
||||
})
|
||||
} finally {
|
||||
setBusyKind(null)
|
||||
setPending(null)
|
||||
callbacks?.onRestartSettled?.()
|
||||
clearPendingAction()
|
||||
if (mountedRef.current) {
|
||||
callbacks?.onRestartSettled?.()
|
||||
}
|
||||
}
|
||||
}, [callbacks])
|
||||
}, [callbacks, clearPendingAction])
|
||||
|
||||
const runKillAll = useCallback(async () => {
|
||||
setBusyKind('killAll')
|
||||
@@ -77,16 +94,19 @@ export function useDaemonActions(callbacks?: DaemonActionCallbacks): DaemonActio
|
||||
toast.error(`${remainingCount} session${remainingCount === 1 ? '' : 's'} refused to exit.`)
|
||||
}
|
||||
} catch (err) {
|
||||
callbacks?.onKillAllError?.()
|
||||
if (mountedRef.current) {
|
||||
callbacks?.onKillAllError?.()
|
||||
}
|
||||
toast.error('Couldn’t kill sessions.', {
|
||||
description: err instanceof Error ? err.message : undefined
|
||||
})
|
||||
} finally {
|
||||
setBusyKind(null)
|
||||
setPending(null)
|
||||
callbacks?.onKillAllSettled?.()
|
||||
clearPendingAction()
|
||||
if (mountedRef.current) {
|
||||
callbacks?.onKillAllSettled?.()
|
||||
}
|
||||
}
|
||||
}, [callbacks])
|
||||
}, [callbacks, clearPendingAction])
|
||||
|
||||
const runConfirmed = useCallback(() => {
|
||||
if (pending === 'restart') {
|
||||
|
||||
@@ -695,6 +695,7 @@ export function ResourceUsageStatusSegment({
|
||||
// somewhere stable for keyboard users.
|
||||
const popoverBodyRef = useRef<HTMLDivElement | null>(null)
|
||||
const popoverBodyFocusFrameRef = useRef<number | null>(null)
|
||||
const mountedRef = useRef(true)
|
||||
|
||||
const cancelPopoverBodyFocusFrame = useCallback((): void => {
|
||||
if (popoverBodyFocusFrameRef.current === null) {
|
||||
@@ -706,6 +707,13 @@ export function ResourceUsageStatusSegment({
|
||||
|
||||
useEffect(() => cancelPopoverBodyFocusFrame, [cancelPopoverBodyFocusFrame])
|
||||
|
||||
useEffect(() => {
|
||||
mountedRef.current = true
|
||||
return () => {
|
||||
mountedRef.current = false
|
||||
}
|
||||
}, [])
|
||||
|
||||
const setPopoverBodyNode = useCallback(
|
||||
(node: HTMLDivElement | null): void => {
|
||||
// Why: the queued post-kill focus is only valid while the popover body exists.
|
||||
@@ -719,16 +727,23 @@ export function ResourceUsageStatusSegment({
|
||||
|
||||
const refreshSessions = useCallback(async () => {
|
||||
if (runtimeEnvironmentActive) {
|
||||
setSessions([])
|
||||
setSessionsError(false)
|
||||
if (mountedRef.current) {
|
||||
setSessions([])
|
||||
setSessionsError(false)
|
||||
}
|
||||
return
|
||||
}
|
||||
try {
|
||||
const result = await window.api.pty.listSessions()
|
||||
if (!mountedRef.current) {
|
||||
return
|
||||
}
|
||||
setSessions(result)
|
||||
setSessionsError(false)
|
||||
} catch {
|
||||
setSessionsError(true)
|
||||
if (mountedRef.current) {
|
||||
setSessionsError(true)
|
||||
}
|
||||
}
|
||||
}, [runtimeEnvironmentActive])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user