From 108390e8236d43bb89836932d2616547f2ac7b9a Mon Sep 17 00:00:00 2001 From: ZGaetano Date: Wed, 3 Jun 2026 12:51:41 +0000 Subject: [PATCH] fix(scheduler): add 90s grace before marking stopped-recorder live assets as error --- services/mam-api/src/scheduler.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/services/mam-api/src/scheduler.js b/services/mam-api/src/scheduler.js index 6787dd9..d77726c 100644 --- a/services/mam-api/src/scheduler.js +++ b/services/mam-api/src/scheduler.js @@ -137,7 +137,10 @@ async function tick() { // Orphaned live assets: recorder stopped but asset still 'live'. // Happens when the capture sidecar crashes before finalize() runs. - // Mark error immediately so the library doesn't show "Recording" forever. + // Wait 90s grace before marking error — this prevents a mam-api restart + // from racing the capture container's finalize() POST, which can take up + // to 30s for large files on a slow upload or busy node. + const ORPHAN_GRACE_SECONDS = parseInt(process.env.ORPHAN_GRACE_SECONDS || '90', 10); const orphanResult = await client.query( `UPDATE assets a SET status = 'error', updated_at = NOW() @@ -145,7 +148,9 @@ async function tick() { WHERE a.status = 'live' AND a.display_name = r.current_session_id AND r.status = 'stopped' - RETURNING a.id, a.display_name` + AND a.updated_at < NOW() - ($1 || ' seconds')::INTERVAL + RETURNING a.id, a.display_name`, + [ORPHAN_GRACE_SECONDS] ); if (orphanResult.rows.length > 0) { for (const row of orphanResult.rows) {