fix: parallel ICY polling with batch size 10 and 5s timeout

This commit is contained in:
nk
2026-06-02 20:15:15 +03:00
parent 6b2e02f6c0
commit d0874ae9db

View File

@@ -17,12 +17,17 @@ 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 {
let successCount = 0;
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) continue;
if (!track) return null;
const updated = await this.prisma.nowPlaying.upsert({
where: { stationId: station.id },
@@ -45,13 +50,25 @@ export class IcyNowPlayingService {
coverUrl: null,
updatedAt: updated.updatedAt,
});
} catch (error) {
return track;
}),
);
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 ${station.name}: ${error.message}`,
`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');