fix(producer): start segmented render workers together so slow media waits overlap (#5573)

* fix(producer): start segmented render workers together so slow media waits overlap

Each worker's page load used to wait for the previous worker's media,
fonts and Tailwind to be ready, so a slow readiness wait was paid once
per worker. Open every worker session at once, as non-segmented
parallel capture already does.

* fix(producer): trim the worker-opening comment

* fix(producer): name the worker-opening helper instead of commenting it
This commit is contained in:
Miguel Ángel
2026-10-14 02:26:11 +00:00
committed by GitHub
parent 6afcb48395
commit d77b03c24c
2 changed files with 43 additions and 1 deletions
@@ -700,6 +700,36 @@ describe("runCaptureSegmentedStage", () => {
expect(createdSessionConfigs).toEqual([expect.objectContaining({ enableBrowserPool: false })]);
});
it("opens every worker's session together, so readiness waits overlap", async () => {
let opening = 0;
let mostOpeningAtOnce = 0;
let id = 0;
const result = await runCaptureSegmentedStage({
...fakeStageInput({ totalFrames: 9 }),
probeSession: null,
segmentFrames: 3,
segmentDir: join(fixtureRoot, "concurrent-open"),
workerCount: 3,
sessionFactory: {
create: async () => {
mostOpeningAtOnce = Math.max(mostOpeningAtOnce, ++opening);
await new Promise((resolve) => setImmediate(resolve));
opening--;
return fakeSession(id++);
},
},
deps: {
spawnEncoder: mock(async () => okEncoder()),
captureFrame: mock(async () => ({ buffer: Buffer.alloc(1) })),
concat: mock(async () => ({ success: true as const })),
closeSession: mock(async () => {}),
removeFile: () => {},
},
});
expect(result.success).toBe(true);
expect(mostOpeningAtOnce).toBe(3);
});
it("closes a fresh session whose initialization fails", async () => {
closeCaptureSession.mockClear();
failInitializeSession = true;
@@ -408,6 +408,18 @@ async function createSegmentWorker(run: SegmentRun, id: number): Promise<Segment
};
}
async function openSegmentWorkersTogether(
run: SegmentRun,
workersToCloseLater: SegmentWorker[],
): Promise<void> {
const opened = await Promise.allSettled(
Array.from({ length: run.workerCount }, (_, id) => createSegmentWorker(run, id)),
);
for (const o of opened) if (o.status === "fulfilled") workersToCloseLater.push(o.value);
const failure = opened.find((o) => o.status === "rejected");
if (failure && failure.status === "rejected") throw failure.reason;
}
/** Close this worker's browser and open a fresh one at a segment boundary. */
async function recycleWorkerSession(
run: SegmentRun,
@@ -585,7 +597,7 @@ export async function runCaptureSegmentedStage(
try {
assertNotAborted();
for (let id = 0; id < run.workerCount; id++) workers.push(await createSegmentWorker(run, id));
await openSegmentWorkersTogether(run, workers);
// allSettled, not all: closing a session out from under a worker that is
// still capturing orphans its ffmpeg and races the CDP connection, so
// every worker has to stop before the finally runs. The first error is