From 22c0916544162f2ddba867189c7bd2014f43018d Mon Sep 17 00:00:00 2001 From: FoxxMD Date: Fri, 1 May 2026 17:58:46 +0000 Subject: [PATCH] Fix counts for scrobbles/dead --- .../scrobblers/AbstractScrobbleClient.ts | 2 +- src/backend/server/api.ts | 60 +++++++++++-------- src/client/status/ducks.ts | 8 +++ 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/src/backend/scrobblers/AbstractScrobbleClient.ts b/src/backend/scrobblers/AbstractScrobbleClient.ts index ec4d5e87..e587249a 100644 --- a/src/backend/scrobblers/AbstractScrobbleClient.ts +++ b/src/backend/scrobblers/AbstractScrobbleClient.ts @@ -244,7 +244,7 @@ export default abstract class AbstractScrobbleClient extends AbstractComponent i protected async postDatabase(): Promise { this.playRepo.componentId = this.dbComponent.id; this.queueRepo.componentId = this.dbComponent.id; - this.tracksScrobbled = this.dbComponent.countLive; + this.tracksScrobbled = this.dbComponent.countLive + this.dbComponent.countNonLive; this.queuedLength = await this.queueRepo.getQueueCount(this.dbComponent.id, [CLIENT_INGRESS_QUEUE]); this.queuedGauge.labels(this.getPrometheusLabels()).set(this.queuedLength); this.deadLetterLength = await this.queueRepo.getQueueCount(this.dbComponent.id, [CLIENT_DEAD_QUEUE], ['queued', 'failed']); diff --git a/src/backend/server/api.ts b/src/backend/server/api.ts index 8bbd8f1b..eae08038 100644 --- a/src/backend/server/api.ts +++ b/src/backend/server/api.ts @@ -239,7 +239,7 @@ export const setupApi = (app: Express, logger: Logger, appLoggerStream: PassThro hasAuthInteraction: requiresAuthInteraction, authed, initialized: x.isReady(), - deadLetterScrobbles: x.deadLetterLength, // x.deadLetterScrobbles.length, + deadLetterScrobbles: x.deadLetterQueued, // x.deadLetterScrobbles.length, queued: x.queuedLength // x.queuedScrobbles.length }; if (!base.initialized) { @@ -326,11 +326,21 @@ export const setupApi = (app: Express, logger: Logger, appLoggerStream: PassThro const { // @ts-expect-error TS(2339): Property 'scrobbleSource' does not exist on type '... Remove this comment to see the full error message scrobbleClient: client, - query + query = {} } = req; + const deadQuery: QueryPlaysOpts = { + ...query as Partial, + queues: [ + { + queueName: CLIENT_DEAD_QUEUE, + queueStatus: 'queued' + } + ] + } + // @ts-ignore - const result: DeadLetterScrobble[] = (await (client as AbstractScrobbleClient).getPlaysPaginated(query as Partial)).data.map(x => playSelectToDeadScrobble); + const result: DeadLetterScrobble[] = (await (client as AbstractScrobbleClient).getPlaysPaginated(deadQuery)).data.map(playSelectToDeadScrobble); return res.json(result); }); @@ -361,20 +371,20 @@ export const setupApi = (app: Express, logger: Logger, appLoggerStream: PassThro (client as AbstractScrobbleClient).logger.verbose(`User requested processing of dead letter scrobble ${deadId} via API call`) - const deadScrobble = (client as AbstractScrobbleClient).deadLetterScrobbles.find(x => x.id === deadId); - - if(deadScrobble === undefined) { - (client as AbstractScrobbleClient).logger.debug(`No dead letter scrobble with ID ${deadId}`) - return res.status(404).send(); - } - - const [scrobbled, dead] = await ((client as AbstractScrobbleClient).processDeadLetterScrobble(undefined, deadId)); - - if(scrobbled) { - return res.status(200).send(); + try { + const [scrobbled, dead] = await (client as AbstractScrobbleClient).processDeadLetterScrobble(undefined, deadId); + if(scrobbled) { + return res.status(200).send(); + } + return res.json(playSelectToDeadScrobble(dead)); + } catch (e) { + if(e.message.includes(`Play ${deadId} does not exist`)) { + logger.warn(e); + return res.status(404).json({error: e}); + } + logger.error(e); + return res.status(500).json({error: e}); } - - return res.json(playSelectToDeadScrobble(dead)); }); app.delete('/api/dead', clientMiddleFunc(true), async (req, res, next) => { @@ -403,15 +413,17 @@ export const setupApi = (app: Express, logger: Logger, appLoggerStream: PassThro (client as AbstractScrobbleClient).logger.verbose(`User requested removal of dead letter scrobble ${deadId} via API call`) - const deadScrobble = (client as AbstractScrobbleClient).deadLetterScrobbles.find(x => x.id === deadId); - - if(deadScrobble === undefined) { - (client as AbstractScrobbleClient).logger.verbose(`No dead letter scrobble with ID ${deadId}`) - return res.status(404).send(); + try { + await (client as AbstractScrobbleClient).removeDeadLetterScrobble(deadId,'failed', false); + return res.status(200).send(); + } catch (e) { + if(e.message.includes(`Play ${deadId} does not exist`)) { + logger.warn(e); + return res.status(404).json({error: e}); + } + logger.error(e); + return res.status(500).json({error: e}); } - - (client as AbstractScrobbleClient).removeDeadLetterScrobble(deadId,'failed', false); - return res.status(200).send(); }); app.get('/api/scrobbled', clientMiddleFunc(false), async (req, res, next) => { diff --git a/src/client/status/ducks.ts b/src/client/status/ducks.ts index d96604c7..78c1d27b 100644 --- a/src/client/status/ducks.ts +++ b/src/client/status/ducks.ts @@ -106,6 +106,14 @@ const clientSlice = createSlice({ } } ) + .addMatcher( + (action) => clientUpdate.match(action) && action.payload.event === 'removeDeadLetter', + (state, action) => { + if(state.entities[action.payload.id] !== undefined) { + state.entities[action.payload.id].deadLetterScrobbles--; + } + } + ) .addMatcher( (action) => clientUpdate.match(action) && action.payload.event === 'statusChange', (state, action) => { -- 2.51.2