(fix) module refresh bug..
This commit is contained in:
@@ -105,6 +105,9 @@ export function useWorkspaceModuleList({
|
||||
const moduleInputsRef = useRef({ curriculumModules, applyModuleParameterOverrides })
|
||||
const loadSequenceRef = useRef(0)
|
||||
const moduleLoadInFlightRef = useRef(false)
|
||||
const queuedModuleLoadRef = useRef<(() => void) | null>(null)
|
||||
const workspaceScopeKey = remoteWorkspace ? `remote:${remoteWorkspaceTargetKey}` : `local:${clonePathPreview}`
|
||||
const previousWorkspaceScopeRef = useRef(workspaceScopeKey)
|
||||
const pendingModuleStatesRef = useRef(new Map<string, { state: ModuleRow['state']; expiresAt: number }>())
|
||||
|
||||
const moduleStateKey = (module: ModuleRow): string => module.folderName ?? module.name
|
||||
@@ -173,7 +176,10 @@ export function useWorkspaceModuleList({
|
||||
const loadAvailableModules = useCallback(async ({ silent = false }: LoadAvailableModulesOptions = {}): Promise<void> => {
|
||||
// Remote probes open an SSH session. Do not let polling overlap a slow
|
||||
// probe, otherwise every response becomes stale and loading never settles.
|
||||
if (moduleLoadInFlightRef.current) return
|
||||
if (moduleLoadInFlightRef.current) {
|
||||
queuedModuleLoadRef.current = () => { void loadAvailableModules({ silent }) }
|
||||
return
|
||||
}
|
||||
moduleLoadInFlightRef.current = true
|
||||
const requestSequence = ++loadSequenceRef.current
|
||||
if (!silent) setModulesLoading(true)
|
||||
@@ -212,6 +218,9 @@ export function useWorkspaceModuleList({
|
||||
} finally {
|
||||
moduleLoadInFlightRef.current = false
|
||||
if (!silent && requestSequence === loadSequenceRef.current) setModulesLoading(false)
|
||||
const queuedLoad = queuedModuleLoadRef.current
|
||||
queuedModuleLoadRef.current = null
|
||||
queuedLoad?.()
|
||||
}
|
||||
}, [
|
||||
applyPendingModuleStates,
|
||||
@@ -223,24 +232,38 @@ export function useWorkspaceModuleList({
|
||||
])
|
||||
|
||||
useEffect(() => {
|
||||
// A response for an earlier module set must not replace newly added rows.
|
||||
++loadSequenceRef.current
|
||||
const sameWorkspace = previousWorkspaceScopeRef.current === workspaceScopeKey
|
||||
previousWorkspaceScopeRef.current = workspaceScopeKey
|
||||
if (!sameWorkspace) pendingModuleStatesRef.current.clear()
|
||||
const cachedModules = readRemoteModuleCache(moduleCacheKey)
|
||||
if (cachedModules) {
|
||||
const modules = applyPendingModuleStates(
|
||||
moduleInputsRef.current.applyModuleParameterOverrides(cachedModules).sort(compareModulePriority),
|
||||
)
|
||||
setAvailableModules(modules)
|
||||
setModuleListError(null)
|
||||
setModulesLoading(false)
|
||||
if (skipInitialModuleLoad) return
|
||||
}
|
||||
setAvailableModules((current) => {
|
||||
const previous = new Map((sameWorkspace && current.length ? current : cachedModules ?? [])
|
||||
.map((module) => [module.folderName ?? module.name, module]))
|
||||
const modules = makeUninstalledModuleRows(moduleInputsRef.current.curriculumModules).map((module) => {
|
||||
const existing = previous.get(module.folderName ?? module.name)
|
||||
return existing ? {
|
||||
...module,
|
||||
state: existing.state,
|
||||
workspacePath: existing.workspacePath,
|
||||
parameters: existing.parameters,
|
||||
cpu: existing.cpu,
|
||||
memory: existing.memory,
|
||||
runtime: existing.runtime,
|
||||
} : module
|
||||
})
|
||||
return applyPendingModuleStates(moduleInputsRef.current.applyModuleParameterOverrides(modules))
|
||||
})
|
||||
setModuleListError(null)
|
||||
setModulesLoading(false)
|
||||
if (!(cachedModules && skipInitialModuleLoad)) void loadAvailableModules()
|
||||
|
||||
if (!cachedModules) {
|
||||
setAvailableModules(makeUninstalledModuleRows(moduleInputsRef.current.curriculumModules))
|
||||
setModuleListError(null)
|
||||
return () => {
|
||||
++loadSequenceRef.current
|
||||
queuedModuleLoadRef.current = null
|
||||
}
|
||||
|
||||
void loadAvailableModules()
|
||||
}, [applyPendingModuleStates, loadAvailableModules, moduleCacheKey, remoteWorkspaceTargetKey, skipInitialModuleLoad])
|
||||
}, [applyPendingModuleStates, loadAvailableModules, moduleCacheKey, skipInitialModuleLoad, workspaceScopeKey])
|
||||
|
||||
useEffect(() => {
|
||||
if (!pollingActive) return
|
||||
|
||||
Reference in New Issue
Block a user