mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-04 07:19:52 +00:00
fix(producer): rethrow disk drawElement verify failure past completeness check
This commit is contained in:
@@ -140,6 +140,28 @@ describe("CapturePlan", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("forces screenshot on a disk-plan drawElement verify failure (PRINFRA-352 recovery)", () => {
|
||||||
|
// Parallel disk workers under the explicit fast-capture opt-in verify their
|
||||||
|
// own captured samples; a breach must re-render the DISK plan on the
|
||||||
|
// screenshot baseline (not throw, and not stay on drawElement).
|
||||||
|
const disk = createCapturePlan({
|
||||||
|
workerCount: 2,
|
||||||
|
forceScreenshot: false,
|
||||||
|
useStreamingEncode: false,
|
||||||
|
useLayeredComposite: false,
|
||||||
|
usePageSideCompositing: false,
|
||||||
|
hasHdrContent: false,
|
||||||
|
needsAlpha: false,
|
||||||
|
});
|
||||||
|
const next = replanAfterFailure(disk, { kind: "draw_element_verification" });
|
||||||
|
expect(next).toMatchObject({
|
||||||
|
kind: "sdr_disk",
|
||||||
|
forceScreenshot: true,
|
||||||
|
forceParallelStream: false,
|
||||||
|
workerCount: 2,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("rejects a streaming transition from a non-streaming plan", () => {
|
it("rejects a streaming transition from a non-streaming plan", () => {
|
||||||
const disk = createCapturePlan({
|
const disk = createCapturePlan({
|
||||||
workerCount: 2,
|
workerCount: 2,
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ import {
|
|||||||
executeParallelCapture,
|
executeParallelCapture,
|
||||||
getCapturePerfSummary,
|
getCapturePerfSummary,
|
||||||
psnrDb,
|
psnrDb,
|
||||||
|
resolveDeVerifyMinDb,
|
||||||
recaptureDrawElementFrameForVerify,
|
recaptureDrawElementFrameForVerify,
|
||||||
completeDeferredDrawElementInit,
|
completeDeferredDrawElementInit,
|
||||||
initializeSession,
|
initializeSession,
|
||||||
@@ -257,14 +258,14 @@ function createDrainFrameGuard(args: {
|
|||||||
// check stops meaning anything); above ~60dB natural DE-vs-screenshot
|
// check stops meaning anything); above ~60dB natural DE-vs-screenshot
|
||||||
// encoder differences (~45dB+) would force a screenshot fallback on every
|
// encoder differences (~45dB+) would force a screenshot fallback on every
|
||||||
// verified render. Out-of-range or malformed values fall back to 32.
|
// verified render. Out-of-range or malformed values fall back to 32.
|
||||||
const verifyMinDbRaw = Number(process.env.HF_DE_VERIFY_MIN_DB ?? "32");
|
// Single-sourced clamp (psnr.ts) so the disk and streaming verify paths can
|
||||||
const verifyMinDb =
|
// never apply different PSNR floors to the same composition. The warn stays
|
||||||
Number.isFinite(verifyMinDbRaw) && verifyMinDbRaw >= 10 && verifyMinDbRaw <= 60
|
// here because only this path has a logger in scope.
|
||||||
? verifyMinDbRaw
|
const verifyMinDb = resolveDeVerifyMinDb();
|
||||||
: 32;
|
const rawEnv = process.env.HF_DE_VERIFY_MIN_DB;
|
||||||
if (process.env.HF_DE_VERIFY_MIN_DB !== undefined && verifyMinDb !== verifyMinDbRaw) {
|
if (rawEnv !== undefined && Number(rawEnv) !== verifyMinDb) {
|
||||||
log.warn("[Render] HF_DE_VERIFY_MIN_DB out of range [10,60]; using 32", {
|
log.warn(`[Render] HF_DE_VERIFY_MIN_DB out of range [10,60]; using ${verifyMinDb}`, {
|
||||||
raw: process.env.HF_DE_VERIFY_MIN_DB,
|
raw: rawEnv,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const sizes: number[] = [];
|
const sizes: number[] = [];
|
||||||
|
|||||||
@@ -1018,6 +1018,20 @@ export async function executeDiskCaptureWithAdaptiveRetry(options: {
|
|||||||
if (failure.kind === "cancelled") {
|
if (failure.kind === "cancelled") {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
// A drawElement self-verify breach (a parallel disk worker's sampled
|
||||||
|
// frame diverged from its pre-injection ground truth) is a CORRECTNESS
|
||||||
|
// failure, not a missing-frame one: the damaged frames are written
|
||||||
|
// complete to disk, so the presence/size-only findMissingFrameRanges
|
||||||
|
// below would count them present and wrongly return success — shipping
|
||||||
|
// the exact compositor damage this verify exists to catch. Rethrow so
|
||||||
|
// the orchestrator's disk-stage screenshot retry fires (mirrors the
|
||||||
|
// `cancelled` guard; a worker-halving retry here would only re-run
|
||||||
|
// drawElement and re-damage). Structural detection walks the aggregated
|
||||||
|
// CaptureFailure → worker CaptureFailure → DrawElementVerificationError
|
||||||
|
// cause chain.
|
||||||
|
if (isDrawElementVerificationError(error)) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
const remaining = findMissingFrameRanges(
|
const remaining = findMissingFrameRanges(
|
||||||
options.totalFrames,
|
options.totalFrames,
|
||||||
options.framesDir,
|
options.framesDir,
|
||||||
|
|||||||
Reference in New Issue
Block a user