fix: glitch toggle gpus (#5353)

* fix: glitch toogle gpu

* fix: Using the GPU's array index as a key for gpuLoading

* enhancement: added try-finally
This commit is contained in:
Faisal Amir 2025-06-18 19:58:24 +07:00 committed by GitHub
parent f5971b9d03
commit 0681c6bb9e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 52 additions and 24 deletions

View File

@ -87,8 +87,17 @@ interface HardwareStore {
// Update RAM available
updateRAMAvailable: (available: number) => void
// Toggle GPU activation
toggleGPUActivation: (index: number) => void
// Toggle GPU activation (async, with loading)
toggleGPUActivation: (index: number) => Promise<void>
// GPU loading state
gpuLoading: { [index: number]: boolean }
setGpuLoading: (index: number, loading: boolean) => void
// Polling control
pollingPaused: boolean
pausePolling: () => void
resumePolling: () => void
// Reorder GPUs
reorderGPUs: (oldIndex: number, newIndex: number) => void
@ -96,8 +105,16 @@ interface HardwareStore {
export const useHardware = create<HardwareStore>()(
persist(
(set) => ({
(set, get) => ({
hardwareData: defaultHardwareData,
gpuLoading: {},
pollingPaused: false,
setGpuLoading: (index, loading) =>
set((state) => ({
gpuLoading: { ...state.gpuLoading, [state.hardwareData.gpus[index].uuid]: loading },
})),
pausePolling: () => set({ pollingPaused: true }),
resumePolling: () => set({ pollingPaused: false }),
setCPU: (cpu) =>
set((state) => ({
@ -172,25 +189,34 @@ export const useHardware = create<HardwareStore>()(
},
})),
toggleGPUActivation: (index) => {
set((state) => {
const newGPUs = [...state.hardwareData.gpus]
if (index >= 0 && index < newGPUs.length) {
newGPUs[index] = {
...newGPUs[index],
activated: !newGPUs[index].activated,
toggleGPUActivation: async (index) => {
const { pausePolling, setGpuLoading, resumePolling } = get();
pausePolling();
setGpuLoading(index, true);
try {
await new Promise((resolve) => setTimeout(resolve, 200)); // Simulate async, replace with real API if needed
set((state) => {
const newGPUs = [...state.hardwareData.gpus];
if (index >= 0 && index < newGPUs.length) {
newGPUs[index] = {
...newGPUs[index],
activated: !newGPUs[index].activated,
};
}
}
setActiveGpus({
gpus: newGPUs.filter((e) => e.activated).map((e) => parseInt(e.id)),
})
return {
hardwareData: {
...state.hardwareData,
gpus: newGPUs,
},
}
})
setActiveGpus({
gpus: newGPUs.filter((e) => e.activated).map((e) => parseInt(e.id)),
});
return {
hardwareData: {
...state.hardwareData,
gpus: newGPUs,
},
};
});
} finally {
setGpuLoading(index, false);
setTimeout(resumePolling, 1000); // Resume polling after 1s
}
},
reorderGPUs: (oldIndex, newIndex) =>

View File

@ -49,7 +49,7 @@ function SortableGPUItem({ gpu, index }: { gpu: GPU; index: number }) {
isDragging,
} = useSortable({ id: gpu.id || index })
const { toggleGPUActivation } = useHardware()
const { toggleGPUActivation, gpuLoading } = useHardware()
const style = {
transform: CSS.Transform.toString(transform),
@ -78,6 +78,7 @@ function SortableGPUItem({ gpu, index }: { gpu: GPU; index: number }) {
<div className="flex items-center gap-4">
<Switch
checked={gpu.activated}
disabled={!!gpuLoading[index]}
onCheckedChange={() => toggleGPUActivation(index)}
/>
</div>
@ -122,6 +123,7 @@ function Hardware() {
updateCPUUsage,
updateRAMAvailable,
reorderGPUs,
pollingPaused,
} = useHardware()
const { vulkanEnabled, setVulkanEnabled } = useVulkan()
@ -155,16 +157,16 @@ function Hardware() {
}
useEffect(() => {
if (pollingPaused) return;
const intervalId = setInterval(() => {
getHardwareInfo().then((data) => {
setHardwareData(data as unknown as HardwareData)
updateCPUUsage(data.cpu.usage)
updateRAMAvailable(data.ram.available)
})
}, 5000)
return () => clearInterval(intervalId)
}, [setHardwareData, updateCPUUsage, updateRAMAvailable])
}, [setHardwareData, updateCPUUsage, updateRAMAvailable, pollingPaused])
const handleClickSystemMonitor = async () => {
try {