diff --git a/services/worker/src/workers/promotion.js b/services/worker/src/workers/promotion.js index 5ad63df..2f95692 100644 --- a/services/worker/src/workers/promotion.js +++ b/services/worker/src/workers/promotion.js @@ -146,6 +146,23 @@ async function promote(filePath) { } const asset = r.rows[0]; + // CRITICAL: do not promote while the recorder is STILL RECORDING this + // session. The mtime-idle heuristic is unreliable over CIFS (attribute + // caching makes an actively-growing MXF look "stable"), which caused the + // worker to grab a live file mid-record (~15s in), upload it, flip the + // asset to 'ready', and unlink it — "a worker is stealing the file". The + // growing asset's display_name IS the recorder's current_session_id, so + // gate on the recorder's live status: only promote once recording stopped. + const recActive = await query( + `SELECT 1 FROM recorders + WHERE current_session_id = $1 AND status = 'recording' LIMIT 1`, + [clipName] + ); + if (recActive.rows.length > 0) { + // Still recording — leave the growing file in place for the editor. + return; + } + const st = await stat(filePath); console.log(`[promotion] uploading ${rel} (${st.size} bytes) -> s3://${S3_BUCKET}/${s3Key}`); await uploadStreamToS3(S3_BUCKET, s3Key, createReadStream(filePath));