perf(enrich): rate-limiter на Discogs + concurrency 5 (обложки быстрее)

Discogs ограничен ≥1.1с между вызовами (≤54/мин, без 429) независимо от
параллельности. Параллельность 5 → обложки (iTunes, без лимита) и скачивание
льются быстрее. Решает медленное наполнение обложек живого набора.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
nk
2026-06-03 20:51:28 +03:00
parent 588857a73e
commit 5164843824
2 changed files with 18 additions and 2 deletions

View File

@@ -33,13 +33,27 @@ export class DiscogsService {
private readonly token = process.env.DISCOGS_TOKEN ?? '';
private readonly userAgent = 'radiOLA/1.0 +https://radiola.app';
// Глобальный rate-limiter: Discogs ~60 запросов/мин. Разносим вызовы ≥1.1с
// независимо от параллельности обогащения (иначе 429).
private nextSlot = 0;
private readonly minIntervalMs = 1100;
// Без токена обогащение жанрами не работает (поиск требует авторизации)
get enabled(): boolean {
return this.token.length > 0;
}
private async rateLimit(): Promise<void> {
const now = Date.now();
const start = Math.max(now, this.nextSlot);
this.nextSlot = start + this.minIntervalMs;
const wait = start - now;
if (wait > 0) await new Promise((r) => setTimeout(r, wait));
}
async lookup(artist: string, song: string): Promise<DiscogsResult | null> {
if (!this.enabled) return null;
await this.rateLimit();
const params = new URLSearchParams({
artist,

View File

@@ -17,8 +17,10 @@ export class EnrichmentService {
// Очередь обогащения с троттлингом (под лимиты Discogs/iTunes)
private readonly queue: string[] = [];
private running = false;
private readonly throttleMs = 1200;
private readonly concurrency = 2;
// Discogs сам себя лимитирует (rate-limiter в DiscogsService), поэтому можно
// выше параллельность: обложки (iTunes, без лимита) льются быстрее.
private readonly throttleMs = 300;
private readonly concurrency = 5;
constructor(
private readonly prisma: PrismaService,