diff --git a/src/now-playing/icy-now-playing.service.ts b/src/now-playing/icy-now-playing.service.ts index 2e596dc..59a740e 100644 --- a/src/now-playing/icy-now-playing.service.ts +++ b/src/now-playing/icy-now-playing.service.ts @@ -17,41 +17,58 @@ export class IcyNowPlayingService { this.logger.log('Starting ICY now playing poll...'); const stations = await this.prisma.station.findMany({ where: { recordStationId: null, isOnline: true }, + take: 50, }); - for (const station of stations) { - try { - const track = await this.parseIcyMetadata(station.streamUrl); - if (!track) continue; + let successCount = 0; - const updated = await this.prisma.nowPlaying.upsert({ - where: { stationId: station.id }, - create: { - stationId: station.id, + for (let i = 0; i < stations.length; i += 10) { + const batch = stations.slice(i, i + 10); + const results = await Promise.allSettled( + batch.map(async (station) => { + const track = await this.parseIcyMetadata(station.streamUrl); + if (!track) return null; + + const updated = await this.prisma.nowPlaying.upsert({ + where: { stationId: station.id }, + create: { + stationId: station.id, + song: track.song, + artist: track.artist, + coverUrl: null, + }, + update: { + song: track.song, + artist: track.artist, + coverUrl: null, + }, + }); + + this.gateway.broadcastNowPlaying(station.stationId.toString(), { song: track.song, artist: track.artist, coverUrl: null, - }, - update: { - song: track.song, - artist: track.artist, - coverUrl: null, - }, - }); + updatedAt: updated.updatedAt, + }); + return track; + }), + ); - this.gateway.broadcastNowPlaying(station.stationId.toString(), { - song: track.song, - artist: track.artist, - coverUrl: null, - updatedAt: updated.updatedAt, - }); - } catch (error) { - this.logger.warn( - `ICY failed for ${station.name}: ${error.message}`, - ); + for (let j = 0; j < results.length; j++) { + const result = results[j]; + if (result.status === 'fulfilled' && result.value) { + successCount++; + } else if (result.status === 'rejected') { + this.logger.warn( + `ICY failed for ${batch[j].name}: ${result.reason?.message || result.reason}`, + ); + } } } - this.logger.log(`ICY poll complete for ${stations.length} stations`); + + this.logger.log( + `ICY poll complete: ${successCount}/${stations.length} stations updated`, + ); } private async parseIcyMetadata( @@ -59,7 +76,7 @@ export class IcyNowPlayingService { ): Promise<{ artist: string; song: string } | null> { const response = await fetch(url, { headers: { 'Icy-MetaData': '1' }, - signal: AbortSignal.timeout(10000), + signal: AbortSignal.timeout(5000), }); const metaintHeader = response.headers.get('icy-metaint');