Queue bounded stream prewarm requests
This commit is contained in:
@@ -67,6 +67,7 @@ import { ingest as collectVideoMetadata, syncListening, linkListening, startThum
|
||||
import { registerCatalogRoutes } from './recommendations.js';
|
||||
import QRCode from 'qrcode';
|
||||
import { createYtdlpPool } from './ytdlp-pool.js';
|
||||
import { createWarmQueue } from './warm-queue.js';
|
||||
import { dirname, join as pathJoin } from 'node:path';
|
||||
|
||||
// A media proxy must not die because one client's stream hit an edge case
|
||||
@@ -728,15 +729,20 @@ function pickFormat(formats, { formatId, wantAudio, wantHeight }) {
|
||||
// GET /api/streams/warm?v=<id> — fire-and-forget: resolve streams into
|
||||
// streamCache so the real /api/streams a moment later is instant. Bounded
|
||||
// so a scrolling user can't queue dozens of yt-dlp processes.
|
||||
const WARM_MAX = 2;
|
||||
let warmActive = 0;
|
||||
const streamWarmQueue = createWarmQueue({
|
||||
concurrency: 2,
|
||||
maxQueued: 8,
|
||||
run: async (id) => {
|
||||
try { if (await media.getReady(id)) return; } catch { /* fall through */ }
|
||||
await resolveStreams(id);
|
||||
},
|
||||
});
|
||||
app.get('/api/streams/warm', async (c) => {
|
||||
const id = (c.req.query('v') || '').trim();
|
||||
if (!/^[A-Za-z0-9_-]{11}$/.test(id)) return c.body(null, 204);
|
||||
if (warmActive >= WARM_MAX) return c.body(null, 204);
|
||||
try { if (await media.getReady(id)) return c.body(null, 204); } catch { /* fall through */ }
|
||||
warmActive++;
|
||||
resolveStreams(id).catch(() => {}).finally(() => { warmActive--; });
|
||||
// Best effort: bounded queue preserves a small burst (e.g. the first three
|
||||
// search cards) while limiting background extractor work.
|
||||
streamWarmQueue.enqueue(id);
|
||||
return c.body(null, 204);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user