Count views and evict server copies by retention criteria before LRU
This commit is contained in:
@@ -601,10 +601,23 @@ app.get('/api/streams/warm', async (c) => {
|
||||
return c.body(null, 204);
|
||||
});
|
||||
|
||||
// One view per client per video per 30 min (a play and its save count once).
|
||||
const viewSeen = new Map(); // `${who}|${id}` -> ms
|
||||
function countView(c, videoId) {
|
||||
const who = (c.req.header('x-forwarded-for') || '').split(',')[0].trim() || c.req.query('fp') || 'local';
|
||||
const key = who + '|' + videoId;
|
||||
const now = Date.now();
|
||||
if (now - (viewSeen.get(key) || 0) < 30 * 60_000) return;
|
||||
viewSeen.set(key, now);
|
||||
if (viewSeen.size > 20000) viewSeen.clear();
|
||||
p2pDb.addView(videoId, now).catch(() => {});
|
||||
}
|
||||
|
||||
// GET /api/streams?v=<videoId> — meta + proxied audio/quality URLs.
|
||||
app.get('/api/streams', async (c) => {
|
||||
const videoId = (c.req.query('v') || '').replace(/[/\\:?<>|*"]/g, '').trim();
|
||||
if (!videoId) return c.json({ ok: false, error: 'missing videoId' }, 400);
|
||||
countView(c, videoId);
|
||||
|
||||
// An upload from the server's own library — no yt-dlp, no media cache.
|
||||
if (isUpload(videoId)) {
|
||||
@@ -1055,7 +1068,13 @@ mkdirSync(MEDIA_DIR, { recursive: true });
|
||||
|
||||
const media = createMediaCache({
|
||||
dir: MEDIA_DIR,
|
||||
db: { getMedia, upsertMedia, deleteMedia, listMedia, listMediaLru, touchMedia, mediaStats },
|
||||
db: {
|
||||
getMedia, upsertMedia, deleteMedia, listMedia, listMediaLru, touchMedia, mediaStats,
|
||||
// Retention (docs/p2p-architecture.md flow 9): cold copies go before popular ones.
|
||||
listMediaEvictionOrder: () => p2pDb.listMediaEvictionOrder({
|
||||
now: Date.now(), keepMinViews: P2P.keepMinViews, keepDays: P2P.keepDays, keepRecentDays: P2P.keepRecentDays,
|
||||
}),
|
||||
},
|
||||
getInfo: async (videoId) => (await resolveStreams(videoId)).info,
|
||||
download: async (videoId, out) => {
|
||||
await withSaveSlot(() => runYtdlpResilient([
|
||||
@@ -1393,6 +1412,7 @@ function cachedDownloadResponse(videoId, fp, row) {
|
||||
app.get('/api/download/:videoId', async (c) => {
|
||||
const videoId = (c.req.param('videoId') || '').replace(/[/\\:?<>|*"]/g, '').trim();
|
||||
if (!videoId) return c.json({ ok: false, error: 'missing videoId' }, 400);
|
||||
countView(c, videoId);
|
||||
|
||||
// Uploads are already a single file on disk — hand it over as-is.
|
||||
if (isUpload(videoId)) {
|
||||
|
||||
Reference in New Issue
Block a user