feat(recordings): add phase6 recording finalization pipeline and simulator support
This commit is contained in:
36
Backend/workers/recordings.ts
Normal file
36
Backend/workers/recordings.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { and, eq, lt } from 'drizzle-orm';
|
||||
|
||||
import { db } from '../db/client';
|
||||
import { recordings } from '../db/schema';
|
||||
|
||||
const STALE_RECORDING_SECONDS = Number(process.env.RECORDING_STALE_SECONDS ?? 60 * 30);
|
||||
|
||||
export const startRecordingsWorker = (): void => {
|
||||
const intervalMs = Number(process.env.RECORDING_WORKER_INTERVAL_MS ?? 30_000);
|
||||
|
||||
setInterval(() => {
|
||||
reconcileStaleRecordings().catch((error) => {
|
||||
console.error('recordings worker failed', error);
|
||||
});
|
||||
}, intervalMs);
|
||||
};
|
||||
|
||||
const reconcileStaleRecordings = async (): Promise<void> => {
|
||||
const staleBefore = new Date(Date.now() - STALE_RECORDING_SECONDS * 1000);
|
||||
|
||||
const stale = await db.query.recordings.findMany({
|
||||
where: and(eq(recordings.status, 'awaiting_upload'), lt(recordings.createdAt, staleBefore)),
|
||||
limit: 100,
|
||||
});
|
||||
|
||||
for (const recording of stale) {
|
||||
await db
|
||||
.update(recordings)
|
||||
.set({
|
||||
status: 'failed',
|
||||
error: 'recording upload timeout',
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(eq(recordings.id, recording.id));
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user