fix(perf): finalize exact worker capture safely

This commit is contained in:
4gray committed 2026-07-27 02:15:59 +02:00
1 parent d3fdbaa2ef
commit 554eecfee0
23 files changed
+2685 -181

No files matched your search

@@ -2,8 +2,10 @@ import type {
EventLoopDelayMetrics,
MainCaptureMetrics,
WorkerCaptureMetrics,
WorkerPostGcHeapCapture,
WorkerRequestPerformanceMetrics,
} from './m3u-refresh-cancellation-contract';
import { WORKER_POST_GC_HEAP_UNAVAILABLE_REASON } from './m3u-refresh-cancellation-contract';
export interface WorkerRequestPerformanceOutcomeTransport {
readonly operation: string | null;
@@ -62,6 +64,9 @@ const THREAD_CPU_REASONS = new Set([
'thread-cpu-usage-invalid',
'thread-cpu-usage-unavailable',
]);
const WORKER_POST_GC_HEAP_UNAVAILABLE_REASONS = new Set<string>(
Object.values(WORKER_POST_GC_HEAP_UNAVAILABLE_REASON)
);
function isRecord(input: unknown): input is Record<string, unknown> {
return typeof input === 'object' && input !== null && !Array.isArray(input);
@@ -84,6 +89,38 @@ function isNullableReason(
return value === null || (typeof value === 'string' && allowed.has(value));
}
function normalizeWorkerPostGcHeapCapture(
input: Record<string, unknown>
): WorkerPostGcHeapCapture {
const postGcHeapUnavailableReason = input['postGcHeapUnavailableReason'];
const postGcHeapUsedBytes = input['postGcHeapUsedBytes'];
if (
Number.isSafeInteger(postGcHeapUsedBytes) &&
Number(postGcHeapUsedBytes) >= 0 &&
postGcHeapUnavailableReason === null
) {
return {
postGcHeapUnavailableReason: null,
postGcHeapUsedBytes: Number(postGcHeapUsedBytes),
};
}
if (
postGcHeapUsedBytes === null &&
typeof postGcHeapUnavailableReason === 'string' &&
WORKER_POST_GC_HEAP_UNAVAILABLE_REASONS.has(postGcHeapUnavailableReason)
) {
return {
postGcHeapUnavailableReason,
postGcHeapUsedBytes: null,
} as WorkerPostGcHeapCapture;
}
return {
postGcHeapUnavailableReason:
WORKER_POST_GC_HEAP_UNAVAILABLE_REASON.INVALID_CAPTURE,
postGcHeapUsedBytes: null,
};
}
function parseEventLoopDelay(
input: unknown
): EventLoopDelayMetrics | null | undefined {
@@ -280,8 +317,12 @@ export function selectMainCaptureGeneration(
);
const onlyRequest =
requests.length === 1 ? (requests[0] ?? null) : null;
const postGcHeap = normalizeWorkerPostGcHeapCapture(
worker.metrics as unknown as Record<string, unknown>
);
return {
...worker.metrics,
...postGcHeap,
eventLoopDelay: onlyRequest?.eventLoopDelay ?? null,
eventLoopDelayUnavailableReason: onlyRequest
? (onlyRequest.eventLoopDelayUnavailableReason ??