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:
@@ -33,13 +33,27 @@ export class DiscogsService {
|
|||||||
private readonly token = process.env.DISCOGS_TOKEN ?? '';
|
private readonly token = process.env.DISCOGS_TOKEN ?? '';
|
||||||
private readonly userAgent = 'radiOLA/1.0 +https://radiola.app';
|
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 {
|
get enabled(): boolean {
|
||||||
return this.token.length > 0;
|
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> {
|
async lookup(artist: string, song: string): Promise<DiscogsResult | null> {
|
||||||
if (!this.enabled) return null;
|
if (!this.enabled) return null;
|
||||||
|
await this.rateLimit();
|
||||||
|
|
||||||
const params = new URLSearchParams({
|
const params = new URLSearchParams({
|
||||||
artist,
|
artist,
|
||||||
|
|||||||
@@ -17,8 +17,10 @@ export class EnrichmentService {
|
|||||||
// Очередь обогащения с троттлингом (под лимиты Discogs/iTunes)
|
// Очередь обогащения с троттлингом (под лимиты Discogs/iTunes)
|
||||||
private readonly queue: string[] = [];
|
private readonly queue: string[] = [];
|
||||||
private running = false;
|
private running = false;
|
||||||
private readonly throttleMs = 1200;
|
// Discogs сам себя лимитирует (rate-limiter в DiscogsService), поэтому можно
|
||||||
private readonly concurrency = 2;
|
// выше параллельность: обложки (iTunes, без лимита) льются быстрее.
|
||||||
|
private readonly throttleMs = 300;
|
||||||
|
private readonly concurrency = 5;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly prisma: PrismaService,
|
private readonly prisma: PrismaService,
|
||||||
|
|||||||
Reference in New Issue
Block a user