mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 17:27:09 +00:00
fix(producer): render telemetry reports beyond-viewport capture as the workers used it
This commit is contained in:
@@ -210,3 +210,15 @@ describe("discardWarmupCapture", () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("getCapturePerfSummary", () => {
|
||||
it("reports the beyond-viewport value the session captured with", () => {
|
||||
const session = makeFakeSession();
|
||||
try {
|
||||
session.options.captureBeyondViewport = false;
|
||||
expect(getCapturePerfSummary(session).captureBeyondViewport).toBe(false);
|
||||
} finally {
|
||||
rmSync(session.outputDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5557,6 +5557,7 @@ export function getCapturePerfSummary(session: CaptureSession): CapturePerfSumma
|
||||
avgSeekMs: Math.round(session.capturePerf.seekMs / frames),
|
||||
avgBeforeCaptureMs: Math.round(session.capturePerf.beforeCaptureMs / frames),
|
||||
avgScreenshotMs: Math.round(session.capturePerf.screenshotMs / frames),
|
||||
captureBeyondViewport: session.options.captureBeyondViewport,
|
||||
p50TotalMs: medianOf(session.capturePerf.frameMs),
|
||||
p95TotalMs: percentileOf(session.capturePerf.frameMs, 0.95),
|
||||
p99TotalMs: percentileOf(session.capturePerf.frameMs, 0.99),
|
||||
|
||||
@@ -272,6 +272,8 @@ export interface CapturePerfSummary {
|
||||
avgSeekMs: number;
|
||||
avgBeforeCaptureMs: number;
|
||||
avgScreenshotMs: number;
|
||||
/** Whether the session captured beyond the viewport, after init turned the request off for a page that fits. */
|
||||
captureBeyondViewport?: boolean;
|
||||
/**
|
||||
* Median per-frame capture time — warmup-robust, unlike `avgTotalMs`
|
||||
* (first frames pay font/image decode + GC that swamps short renders'
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { buildRenderPerfSummary, roundDb } from "./perfSummary.js";
|
||||
import { buildRenderPerfSummary, capturedBeyondViewport, roundDb } from "./perfSummary.js";
|
||||
import type { CapturePerfSummary } from "@hyperframes/engine";
|
||||
import type { RenderJob } from "../renderOrchestrator.js";
|
||||
|
||||
describe("roundDb", () => {
|
||||
@@ -75,3 +76,21 @@ describe("buildRenderPerfSummary drawElement gate reason", () => {
|
||||
expect(summary.drawElement?.gateReason).toBe("css_effect:filter");
|
||||
});
|
||||
});
|
||||
|
||||
describe("capturedBeyondViewport", () => {
|
||||
const perf = (captureBeyondViewport?: boolean) =>
|
||||
({ captureBeyondViewport }) as CapturePerfSummary;
|
||||
|
||||
it("reports off when every worker's session turned the requested capture off", () => {
|
||||
expect(capturedBeyondViewport([perf(false), perf(false)], true)).toBe(false);
|
||||
});
|
||||
|
||||
it("reports on when any worker kept it", () => {
|
||||
expect(capturedBeyondViewport([perf(false), perf(true)], false)).toBe(true);
|
||||
});
|
||||
|
||||
it("keeps the stage's value when no worker reported one", () => {
|
||||
expect(capturedBeyondViewport([perf()], true)).toBe(true);
|
||||
expect(capturedBeyondViewport([], undefined)).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -54,6 +54,15 @@ export function pushWorkerDedupPerfs(
|
||||
}
|
||||
}
|
||||
|
||||
/** Beyond-viewport capture as the workers' sessions used it: on if any kept it, `fallback` when none reported. */
|
||||
export function capturedBeyondViewport(
|
||||
perfs: ReadonlyArray<CapturePerfSummary>,
|
||||
fallback: boolean | undefined,
|
||||
): boolean | undefined {
|
||||
const used = perfs.flatMap((perf) => perf.captureBeyondViewport ?? []);
|
||||
return used.length > 0 ? used.includes(true) : fallback;
|
||||
}
|
||||
|
||||
/** Adds each worker's page-error console lines to `sink`, once per distinct line. */
|
||||
export function pushWorkerPageErrors(
|
||||
results: ReadonlyArray<{ pageErrorLines?: string[] }>,
|
||||
|
||||
@@ -177,6 +177,7 @@ import { formatCaptureFrameName } from "../utils/paths.js";
|
||||
import { findRenderHdrAutoPromotionTrigger, resolveEffectiveHdrMode } from "./render/hdrMode.js";
|
||||
import {
|
||||
buildRenderPerfSummary,
|
||||
capturedBeyondViewport,
|
||||
pushWorkerDedupPerfs,
|
||||
pushWorkerPageErrors,
|
||||
roundDb,
|
||||
@@ -5150,10 +5151,12 @@ async function executeRenderPipeline(input: {
|
||||
deDrainStats = streamingRes.deDrainStats;
|
||||
workerCount = streamingRes.workerCount;
|
||||
updateCaptureObservability({ workerCount });
|
||||
if (streamingRes.captureBeyondViewport !== undefined) {
|
||||
updateCaptureObservability({
|
||||
captureBeyondViewport: streamingRes.captureBeyondViewport,
|
||||
});
|
||||
const usedBeyondViewport = capturedBeyondViewport(
|
||||
dedupPerfs,
|
||||
streamingRes.captureBeyondViewport,
|
||||
);
|
||||
if (usedBeyondViewport !== undefined) {
|
||||
updateCaptureObservability({ captureBeyondViewport: usedBeyondViewport });
|
||||
}
|
||||
probeSession = streamingRes.probeSession;
|
||||
lastBrowserConsole = streamingRes.lastBrowserConsole;
|
||||
@@ -5337,10 +5340,12 @@ async function executeRenderPipeline(input: {
|
||||
const captureFrameMs = Date.now() - captureFrameStart;
|
||||
workerCount = captureRes.workerCount;
|
||||
updateCaptureObservability({ workerCount });
|
||||
if (captureRes.captureBeyondViewport !== undefined) {
|
||||
updateCaptureObservability({
|
||||
captureBeyondViewport: captureRes.captureBeyondViewport,
|
||||
});
|
||||
const usedBeyondViewport = capturedBeyondViewport(
|
||||
dedupPerfs,
|
||||
captureRes.captureBeyondViewport,
|
||||
);
|
||||
if (usedBeyondViewport !== undefined) {
|
||||
updateCaptureObservability({ captureBeyondViewport: usedBeyondViewport });
|
||||
}
|
||||
probeSession = captureRes.probeSession;
|
||||
lastBrowserConsole = captureRes.lastBrowserConsole;
|
||||
|
||||
Reference in New Issue
Block a user