Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions apps/web/__tests__/unit/finalize-desktop-recording.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,30 @@ describe("durable post-publication transcription enqueue", () => {
expect(mocks.claim).not.toHaveBeenCalled();
});

it("finishes after repeated transcription queue failures", async () => {
withCurrent({ state: "verified" });
mocks.transcribe.mockResolvedValue({
success: false,
message: "Queue unavailable",
});
mocks.sleep.mockImplementation(async () => {
if (mocks.transcribe.mock.calls.length >= 12) {
throw new Error("Transcription retry limit exceeded");
}
});

await expect(
finalizeDesktopRecordingWorkflow({
videoId,
userId,
generation: fixture.generation,
}),
).resolves.toEqual({ success: true });
expect(mocks.transcribe).toHaveBeenCalledTimes(12);
expect(mocks.fetch).not.toHaveBeenCalled();
expect(mocks.claim).not.toHaveBeenCalled();
});

it.each(["unconfigured", "deleted"])(
"skips %s transcription without retrying forever",
async (reason) => {
Expand Down
9 changes: 6 additions & 3 deletions apps/web/workflows/finalize-desktop-recording.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ const PRESIGNED_EXPIRES_SECONDS = 6 * 60 * 60;
const MULTIPART_OUTPUT_PART_SIZE_BYTES = 64 * 1024 * 1024;
const SOURCE_COMMIT_BATCH_MAX_CHECKPOINTS = 32;
const SOURCE_COMMIT_BATCH_DURATION_MS = 15_000;
const TRANSCRIPTION_QUEUE_MAX_ATTEMPTS = 12;

function getErrorMessage(error: unknown) {
return error instanceof Error ? error.message : String(error);
Expand Down Expand Up @@ -190,7 +191,7 @@ export async function finalizeDesktopRecordingWorkflow(
if (retained !== "retry") return { success: false, reason: retained };
}
}
for (let attempt = 0; ; attempt++) {
for (let attempt = 0; attempt < TRANSCRIPTION_QUEUE_MAX_ATTEMPTS; attempt++) {
let queued: boolean;
try {
queued = await queueFinalizedRecordingTranscription(
Expand All @@ -201,7 +202,9 @@ export async function finalizeDesktopRecordingWorkflow(
queued = false;
}
if (queued) break;
await sleep(Math.min(15_000 * 2 ** Math.min(attempt, 5), 300_000));
if (attempt + 1 < TRANSCRIPTION_QUEUE_MAX_ATTEMPTS) {
await sleep(Math.min(15_000 * 2 ** Math.min(attempt, 5), 300_000));
}
}
return mediaServerUnavailable
? { success: false, reason: "media-server-unconfigured" }
Expand Down Expand Up @@ -780,7 +783,7 @@ async function queueFinalizedRecordingTranscription(
);
if (result.success) return true;
console.warn(
"[finalizeDesktopRecordingWorkflow] Transcription enqueue will retry",
"[finalizeDesktopRecordingWorkflow] Transcription enqueue failed",
{ videoId, message: result.message },
);
} catch (error) {
Expand Down
Loading