Fix OOM : heap 4 GB + LRU plafonne par taille (entry 300 MB, search 100 MB)

This commit is contained in:
unfr
2026-06-01 11:14:59 +02:00
parent 92005a9cbe
commit e7017bd3b5
2 changed files with 26 additions and 4 deletions

View File

@@ -8,8 +8,8 @@
"node": ">=20" "node": ">=20"
}, },
"scripts": { "scripts": {
"start": "node --env-file-if-exists=.env server.js", "start": "node --max-old-space-size=4096 --env-file-if-exists=.env server.js",
"cron": "node --env-file-if-exists=.env cron/runAll.js", "cron": "node --max-old-space-size=4096 --env-file-if-exists=.env cron/runAll.js",
"cron:imdb": "node --env-file-if-exists=.env cron/imdbRatings.js", "cron:imdb": "node --env-file-if-exists=.env cron/imdbRatings.js",
"cron:tmdb": "node --env-file-if-exists=.env cron/tmdbSync.js", "cron:tmdb": "node --env-file-if-exists=.env cron/tmdbSync.js",
"cron:justwatch": "node --env-file-if-exists=.env cron/justwatchSync.js", "cron:justwatch": "node --env-file-if-exists=.env cron/justwatchSync.js",

View File

@@ -18,12 +18,34 @@ import { parseQuery } from '../lib/queryParser.js';
import { search as runSearch } from '../lib/searchEngine.js'; import { search as runSearch } from '../lib/searchEngine.js';
import { filterAndLower } from '../lib/titleFilter.js'; import { filterAndLower } from '../lib/titleFilter.js';
const searchCache = new LRUCache({ max: 1000, ttl: 1000 * 60 * 60 }); // Rough byte size of a cached value. Strings + numbers + nested objects via
// JSON length — good enough for cap enforcement, fast (no deep walk).
const sizeOf = (v) => {
if (v == null) return 8;
try {
return JSON.stringify(v).length;
} catch {
return 1024;
}
};
const searchCache = new LRUCache({
max: 1000,
maxSize: 100 * 1024 * 1024, // 100 MB
sizeCalculation: sizeOf,
ttl: 1000 * 60 * 60,
});
// Entry cache covers movie/tv/imdb/providers responses. Keeps hot files in RAM // Entry cache covers movie/tv/imdb/providers responses. Keeps hot files in RAM
// so repeat lookups skip disk + JSON.parse. TTL 30 min (cron may rewrite // so repeat lookups skip disk + JSON.parse. TTL 30 min (cron may rewrite
// underlying detail file via /changes — 30 min keeps staleness bounded). // underlying detail file via /changes — 30 min keeps staleness bounded).
const entryCache = new LRUCache({ max: 5000, ttl: 1000 * 60 * 30 }); // Capped at 300 MB to avoid OOM (TMDB tv detail can hit 500 KB each).
const entryCache = new LRUCache({
max: 2000,
maxSize: 300 * 1024 * 1024, // 300 MB
sizeCalculation: sizeOf,
ttl: 1000 * 60 * 30,
});
async function getDetail(type, id) { async function getDetail(type, id) {
const key = `d:${type}:${id}`; const key = `d:${type}:${id}`;