import React, { useState, useEffect, useRef, useMemo } from 'react'; import { GPUApiResponse } from '@/types'; import Loading from '@/components/Loading'; import GPUWidget from '@/components/GPUWidget'; import { apiClient } from '@/utils/api'; const GpuMonitor: React.FC = () => { const [gpuData, setGpuData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [lastUpdated, setLastUpdated] = useState(null); const isFetchingGpuRef = useRef(false); useEffect(() => { const fetchGpuInfo = async () => { if (isFetchingGpuRef.current) { return; } setLoading(true); isFetchingGpuRef.current = true; apiClient .get('/api/gpu') .then(res => res.data) .then(data => { setGpuData(data); setLastUpdated(new Date()); setError(null); }) .catch(err => { setError(`Failed to fetch GPU data: ${err instanceof Error ? err.message : String(err)}`); }) .finally(() => { isFetchingGpuRef.current = false; setLoading(false); }); }; // Fetch immediately on component mount fetchGpuInfo(); // Set up interval to fetch every 1 seconds const intervalId = setInterval(fetchGpuInfo, 1000); // Clean up interval on component unmount return () => clearInterval(intervalId); }, []); const getGridClasses = (gpuCount: number): string => { switch (gpuCount) { case 1: return 'grid-cols-1'; case 2: return 'grid-cols-2'; case 3: return 'grid-cols-3'; case 4: return 'grid-cols-4'; case 5: case 6: return 'grid-cols-3'; case 7: case 8: return 'grid-cols-4'; case 9: case 10: return 'grid-cols-5'; default: return 'grid-cols-3'; } }; console.log('state', { loading, gpuData, error, lastUpdated, }); const content = useMemo(() => { if (loading && !gpuData) { return ; } if (error) { return (
Error! {error}
); } if (!gpuData) { return (
No GPU data available.
); } if (!gpuData.hasNvidiaSmi) { return (
No NVIDIA GPUs detected! nvidia-smi is not available on this system. {gpuData.error &&

{gpuData.error}

}
); } if (gpuData.gpus.length === 0) { return (
No GPUs found, but nvidia-smi is available.
); } const gridClass = getGridClasses(gpuData?.gpus?.length || 1); return (
{gpuData.gpus.map((gpu, idx) => ( ))}
); }, [loading, gpuData, error]); return (

GPU Monitor

Last updated: {lastUpdated?.toLocaleTimeString()}
{content}
); }; export default GpuMonitor;