49 lines
2.2 KiB
TypeScript
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
|
|
}
|
|
}
|