perf: optimize app startup and background lifecycles
This commit is contained in:
65
electron/main/gpu-fallback.ts
Normal file
65
electron/main/gpu-fallback.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
||||
import { dirname } from 'node:path';
|
||||
|
||||
export const GPU_CRASH_WINDOW_MS = 10 * 60 * 1000;
|
||||
export const GPU_CRASH_THRESHOLD = 2;
|
||||
|
||||
export type GpuFallbackState = {
|
||||
crashCount: number;
|
||||
lastCrashAt: number;
|
||||
reason: string;
|
||||
};
|
||||
|
||||
function isState(value: unknown): value is GpuFallbackState {
|
||||
if (!value || typeof value !== 'object') return false;
|
||||
const record = value as Record<string, unknown>;
|
||||
return Number.isFinite(record.crashCount)
|
||||
&& Number.isFinite(record.lastCrashAt)
|
||||
&& typeof record.reason === 'string';
|
||||
}
|
||||
|
||||
export function readGpuFallbackState(
|
||||
filePath: string,
|
||||
now = Date.now(),
|
||||
): GpuFallbackState | null {
|
||||
try {
|
||||
const parsed: unknown = JSON.parse(readFileSync(filePath, 'utf8'));
|
||||
if (!isState(parsed)) return null;
|
||||
if (now - parsed.lastCrashAt > GPU_CRASH_WINDOW_MS) return null;
|
||||
return parsed;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function shouldUseSoftwareRendering(input: {
|
||||
envDisabled?: boolean;
|
||||
cliDisabled?: boolean;
|
||||
state?: GpuFallbackState | null;
|
||||
now?: number;
|
||||
}): boolean {
|
||||
if (input.envDisabled || input.cliDisabled) return true;
|
||||
const state = input.state;
|
||||
if (!state) return false;
|
||||
const now = input.now ?? Date.now();
|
||||
return now - state.lastCrashAt <= GPU_CRASH_WINDOW_MS
|
||||
&& state.crashCount >= GPU_CRASH_THRESHOLD;
|
||||
}
|
||||
|
||||
export function recordGpuCrash(
|
||||
filePath: string,
|
||||
reason: string,
|
||||
now = Date.now(),
|
||||
): GpuFallbackState {
|
||||
const previous = readGpuFallbackState(filePath, now);
|
||||
const next: GpuFallbackState = {
|
||||
crashCount: previous ? previous.crashCount + 1 : 1,
|
||||
lastCrashAt: now,
|
||||
reason,
|
||||
};
|
||||
mkdirSync(dirname(filePath), { recursive: true });
|
||||
const temporaryPath = `${filePath}.${process.pid}.tmp`;
|
||||
writeFileSync(temporaryPath, `${JSON.stringify(next)}\n`, 'utf8');
|
||||
renameSync(temporaryPath, filePath);
|
||||
return next;
|
||||
}
|
||||
Reference in New Issue
Block a user