mirror of
https://github.com/lone-cloud/gerbil
synced 2026-06-03 19:54:44 -07:00
fix: reduce Windows hardware detection hangs
- Replace siCpu() with synchronous os.cpus() — no PowerShell needed - Replace siMem() with os.totalmem() in detectSystemMemory - Add 3s timeout to siMemLayout() and siGraphics() so they don't block indefinitely behind monitoring's PowerShell queue - Slow memory polling to 3s on Windows (was 1s) to free up the shared PowerShell session for hardware detection queries - Split SystemTab loading: render version info immediately, hardware info fills in as background tasks complete
This commit is contained in:
parent
350c607d7c
commit
0aa967be9e
4 changed files with 37 additions and 42 deletions
|
|
@ -24,7 +24,13 @@ export const SystemTab = () => {
|
||||||
|
|
||||||
setVersionInfo(info);
|
setVersionInfo(info);
|
||||||
setKoboldVersion(currentBackend?.version ?? null);
|
setKoboldVersion(currentBackend?.version ?? null);
|
||||||
|
} catch (error) {
|
||||||
|
window.electronAPI.logs.logError('Failed to load system info', error as Error);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
const [cpu, gpu, gpuCapabilities, gpuMemory, systemMemory] = await Promise.all([
|
const [cpu, gpu, gpuCapabilities, gpuMemory, systemMemory] = await Promise.all([
|
||||||
window.electronAPI.kobold.detectCPU(),
|
window.electronAPI.kobold.detectCPU(),
|
||||||
window.electronAPI.kobold.detectGPU(),
|
window.electronAPI.kobold.detectGPU(),
|
||||||
|
|
@ -41,9 +47,7 @@ export const SystemTab = () => {
|
||||||
systemMemory,
|
systemMemory,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.electronAPI.logs.logError('Failed to load system info', error as Error);
|
window.electronAPI.logs.logError('Failed to load hardware info', error as Error);
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
|
import { cpus as osCpus, totalmem } from 'node:os';
|
||||||
import { platform } from 'node:process';
|
import { platform } from 'node:process';
|
||||||
|
|
||||||
import { execa } from 'execa';
|
import { execa } from 'execa';
|
||||||
import { cpu as siCpu, mem as siMem, memLayout as siMemLayout } from 'systeminformation';
|
import { memLayout as siMemLayout } from 'systeminformation';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
BasicGPUInfo,
|
BasicGPUInfo,
|
||||||
|
|
@ -33,36 +34,26 @@ let basicGPUInfoCache: BasicGPUInfo | null = null;
|
||||||
let gpuCapabilitiesCache: GPUCapabilities | null = null;
|
let gpuCapabilitiesCache: GPUCapabilities | null = null;
|
||||||
let gpuMemoryInfoCache: GPUMemoryInfo[] | null = null;
|
let gpuMemoryInfoCache: GPUMemoryInfo[] | null = null;
|
||||||
|
|
||||||
export async function detectCPU() {
|
export function detectCPU() {
|
||||||
if (cpuCapabilitiesCache) {
|
if (cpuCapabilitiesCache) {
|
||||||
return cpuCapabilitiesCache;
|
return cpuCapabilitiesCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await safeExecute(async () => {
|
const cpuList = osCpus();
|
||||||
const cpu = await siCpu();
|
const brand = cpuList[0]?.model;
|
||||||
|
const cores = cpuList.length;
|
||||||
|
const speed = (cpuList[0]?.speed ?? 0) / 1000;
|
||||||
|
|
||||||
const devices: { name: string; detailedName: string }[] = [];
|
const devices: { name: string; detailedName: string }[] = [];
|
||||||
if (cpu.brand) {
|
if (brand) {
|
||||||
const name = formatDeviceName(cpu.brand);
|
const name = formatDeviceName(brand);
|
||||||
|
devices.push({
|
||||||
devices.push({
|
detailedName: `${name} (${cores} cores) @ ${speed} GHz`,
|
||||||
detailedName: `${name} (${cpu.cores} cores) @ ${cpu.speed} GHz`,
|
name,
|
||||||
name,
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const capabilities = {
|
|
||||||
devices,
|
|
||||||
};
|
|
||||||
|
|
||||||
cpuCapabilitiesCache = capabilities;
|
|
||||||
return capabilities;
|
|
||||||
}, 'CPU detection failed');
|
|
||||||
|
|
||||||
cpuCapabilitiesCache = result ?? {
|
|
||||||
devices: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
|
cpuCapabilitiesCache = { devices };
|
||||||
return cpuCapabilitiesCache;
|
return cpuCapabilitiesCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -370,10 +361,13 @@ export async function detectGPUMemory() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const detectSystemMemory = async () => {
|
export const detectSystemMemory = async () => {
|
||||||
try {
|
const totalGB = (totalmem() / 1024 ** 3).toFixed(2);
|
||||||
const [memInfo, memLayout] = await Promise.all([siMem(), siMemLayout()]);
|
|
||||||
|
|
||||||
const totalGB = (memInfo.total / 1024 ** 3).toFixed(2);
|
try {
|
||||||
|
const memLayout = await Promise.race([
|
||||||
|
siMemLayout(),
|
||||||
|
new Promise<never>((_, reject) => setTimeout(() => reject(new Error('timeout')), 3000)),
|
||||||
|
]);
|
||||||
|
|
||||||
let speed: number | undefined;
|
let speed: number | undefined;
|
||||||
let type: string | undefined;
|
let type: string | undefined;
|
||||||
|
|
@ -394,15 +388,8 @@ export const detectSystemMemory = async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return { speed, totalGB, type };
|
||||||
speed,
|
|
||||||
totalGB,
|
|
||||||
type,
|
|
||||||
};
|
|
||||||
} catch {
|
} catch {
|
||||||
const mem = await siMem();
|
return { totalGB };
|
||||||
return {
|
|
||||||
totalGB: (mem.total / 1024 ** 3).toFixed(2),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ let memoryInterval: ReturnType<typeof setInterval> | null = null;
|
||||||
let gpuInterval: ReturnType<typeof setInterval> | null = null;
|
let gpuInterval: ReturnType<typeof setInterval> | null = null;
|
||||||
let isRunning = false;
|
let isRunning = false;
|
||||||
const updateFrequency = 1000;
|
const updateFrequency = 1000;
|
||||||
|
const memoryUpdateFrequency = platform === 'win32' ? 3000 : updateFrequency;
|
||||||
let mainWindow: BrowserWindow | null = null;
|
let mainWindow: BrowserWindow | null = null;
|
||||||
|
|
||||||
let latestCpuMetrics: CpuMetrics | null = null;
|
let latestCpuMetrics: CpuMetrics | null = null;
|
||||||
|
|
@ -87,7 +88,7 @@ export function startMonitoring(window: BrowserWindow) {
|
||||||
void collectAndSendMemoryMetrics();
|
void collectAndSendMemoryMetrics();
|
||||||
memoryInterval = setInterval(() => {
|
memoryInterval = setInterval(() => {
|
||||||
void collectAndSendMemoryMetrics();
|
void collectAndSendMemoryMetrics();
|
||||||
}, updateFrequency);
|
}, memoryUpdateFrequency);
|
||||||
|
|
||||||
if (platform === 'linux') {
|
if (platform === 'linux') {
|
||||||
void collectAndSendGpuMetrics();
|
void collectAndSendGpuMetrics();
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,10 @@ async function getLinuxGPUData() {
|
||||||
|
|
||||||
async function getWindowsGPUData() {
|
async function getWindowsGPUData() {
|
||||||
try {
|
try {
|
||||||
const graphics = await siGraphics();
|
const graphics = await Promise.race([
|
||||||
|
siGraphics(),
|
||||||
|
new Promise<never>((_, reject) => setTimeout(() => reject(new Error('timeout')), 3000)),
|
||||||
|
]);
|
||||||
|
|
||||||
const discreteControllers = graphics.controllers.filter(
|
const discreteControllers = graphics.controllers.filter(
|
||||||
(controller) => controller.vram && controller.vram >= 1024,
|
(controller) => controller.vram && controller.vram >= 1024,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue