Files
goodbuddy/src/main/inference-process-resources.ts
T

49 lines
2.2 KiB
TypeScript

import type { ProcessMetric } from 'electron'
import type { InferenceResources } from '../shared/local-inference-contracts'
// One sampler per transport: a replacement process never inherits the old baseline.
export function createInferenceProcessSampler(
getPid: () => number | undefined,
getMetrics: () => ProcessMetric[],
now: () => number = () => performance.now()
): () => InferenceResources {
let previous: { pid: number; creationTime: number; time: number; cpu: number } | undefined
return () => {
const pid = getPid()
let metric: ProcessMetric | undefined
try {
if (pid !== undefined) metric = getMetrics().find((entry) => entry.pid === pid && entry.type === 'Utility')
} catch {
previous = undefined
return { scope: 'unavailable', reason: '进程资源采样失败' }
}
if (!metric) {
previous = undefined
return { scope: 'unavailable', reason: pid === undefined ? '服务进程未运行' : '等待进程资源数据' }
}
const time = now()
const cpu = metric.cpu.cumulativeCPUUsage
const resources: InferenceResources = {
scope: 'service-process', pid: metric.pid, sampledAt: Date.now(),
cpuUnavailableReason: '正在建立采样基线'
}
// Electron reports working set in KiB. Do not replace absent readings with zero.
const memory = metric.memory?.workingSetSize
if (Number.isFinite(memory) && memory >= 0) resources.workingSetBytes = memory * 1024
else resources.memoryUnavailableReason = '系统未提供工作集内存'
if (cpu !== undefined && Number.isFinite(cpu) && cpu >= 0) {
if (previous && previous.pid === metric.pid && previous.creationTime === metric.creationTime &&
time > previous.time && time - previous.time <= 15000 && cpu >= previous.cpu) {
// Single-core capacity is 100%; multithreaded inference may exceed 100%.
resources.cpuPercent = (cpu - previous.cpu) * 100_000 / (time - previous.time)
resources.cpuUnavailableReason = undefined
}
previous = { pid: metric.pid, creationTime: metric.creationTime, time, cpu }
} else {
previous = undefined
resources.cpuUnavailableReason = '系统未提供进程 CPU 时间'
}
return resources
}
}