fix: parallel ICY polling with batch size 10 and 5s timeout
This commit is contained in:
@@ -17,12 +17,17 @@ export class IcyNowPlayingService {
|
|||||||
this.logger.log('Starting ICY now playing poll...');
|
this.logger.log('Starting ICY now playing poll...');
|
||||||
const stations = await this.prisma.station.findMany({
|
const stations = await this.prisma.station.findMany({
|
||||||
where: { recordStationId: null, isOnline: true },
|
where: { recordStationId: null, isOnline: true },
|
||||||
|
take: 50,
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const station of stations) {
|
let successCount = 0;
|
||||||
try {
|
|
||||||
|
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);
|
const track = await this.parseIcyMetadata(station.streamUrl);
|
||||||
if (!track) continue;
|
if (!track) return null;
|
||||||
|
|
||||||
const updated = await this.prisma.nowPlaying.upsert({
|
const updated = await this.prisma.nowPlaying.upsert({
|
||||||
where: { stationId: station.id },
|
where: { stationId: station.id },
|
||||||
@@ -45,13 +50,25 @@ export class IcyNowPlayingService {
|
|||||||
coverUrl: null,
|
coverUrl: null,
|
||||||
updatedAt: updated.updatedAt,
|
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(
|
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(
|
private async parseIcyMetadata(
|
||||||
@@ -59,7 +76,7 @@ export class IcyNowPlayingService {
|
|||||||
): Promise<{ artist: string; song: string } | null> {
|
): Promise<{ artist: string; song: string } | null> {
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
headers: { 'Icy-MetaData': '1' },
|
headers: { 'Icy-MetaData': '1' },
|
||||||
signal: AbortSignal.timeout(10000),
|
signal: AbortSignal.timeout(5000),
|
||||||
});
|
});
|
||||||
|
|
||||||
const metaintHeader = response.headers.get('icy-metaint');
|
const metaintHeader = response.headers.get('icy-metaint');
|
||||||
|
|||||||
Reference in New Issue
Block a user