fix: yeniden başlatma sonrası açık kalan session'ları temizle
Bir redeploy, devam eden capture'ı temizlik kodu hiç çalışmadan öldürüyordu — StreamSession.endedAt sonsuza dek null kalıyordu. Bu sadece panelde yanlış "kayıtta" göstermekle kalmıyor, startSession() açık bir session gördüğünde o kanal için yeni session başlatmayı tamamen atlıyor — yani o kanal bir daha asla kayda alınamıyordu. api-daemon başlarken artık tüm açık session'ları kapatıyor (taze bir process başlangıcı = gerçekte devam eden capture yok demektir). BullMQ lockDuration da 24 saatten 10 dakikaya indirildi — worker canlıyken kilit otomatik yenileniyor, düşük değer sadece ölü bir worker'ın job'ının ne kadar hızlı kurtarılacağını etkiliyor. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -181,8 +181,12 @@ export function startStreamIngestWorker(): Worker<StreamIngestJob> {
|
|||||||
// count; the real ceiling is the server's CPU/bandwidth for running that
|
// count; the real ceiling is the server's CPU/bandwidth for running that
|
||||||
// many yt-dlp+ffmpeg pairs at once, not this number.
|
// many yt-dlp+ffmpeg pairs at once, not this number.
|
||||||
concurrency: env.maxConcurrentCaptures,
|
concurrency: env.maxConcurrentCaptures,
|
||||||
// Captures run for the lifetime of the stream (can be hours) — extend the
|
// BullMQ renews this lock automatically while a worker is alive, so a
|
||||||
// default lock well beyond BullMQ's stalled-job assumptions for an MVP.
|
// low value doesn't cap how long a capture can run — it only controls
|
||||||
lockDuration: 24 * 60 * 60 * 1000,
|
// how fast a *dead* worker's job is detected as stalled and recovered.
|
||||||
|
// (An earlier 24h value meant a killed process's job wouldn't be
|
||||||
|
// recovered for up to 24h; closeOrphanedSessions() in index.ts is what
|
||||||
|
// actually unblocks that channel's StreamSession in the meantime.)
|
||||||
|
lockDuration: 10 * 60 * 1000,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,28 @@ async function forceLiveBypass(youtubeUrl: string) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A container restart (e.g. a redeploy) kills any in-progress capture
|
||||||
|
* without running its cleanup code, leaving that StreamSession's endedAt
|
||||||
|
* stuck at null forever. Besides showing "still recording" in the panel,
|
||||||
|
* startSession() treats any open session as a reason to skip starting a new
|
||||||
|
* one for that channel — so an orphaned session permanently blocks that
|
||||||
|
* channel from ever being recorded again until this runs. Since a fresh
|
||||||
|
* process start means no capture can actually still be in progress, every
|
||||||
|
* open session at boot is stale by definition and gets closed out.
|
||||||
|
*/
|
||||||
|
async function closeOrphanedSessions() {
|
||||||
|
const { count } = await prisma.streamSession.updateMany({
|
||||||
|
where: { endedAt: null },
|
||||||
|
data: { endedAt: new Date() },
|
||||||
|
});
|
||||||
|
if (count > 0) {
|
||||||
|
console.log(`[index] closed ${count} orphaned session(s) left open by a previous process`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
|
await closeOrphanedSessions();
|
||||||
startServer();
|
startServer();
|
||||||
startStreamIngestWorker();
|
startStreamIngestWorker();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user