mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 23:05:46 +00:00
fix: prune stale analysis queues and cap loudness backfill window (#480)
* fix(analysis): prune stale backfill jobs and limit prefetch window Drop pending backfill and cpu-seed jobs that are no longer in the active playback queue, and add debug counters for pruned work. Limit loudness backfill scheduling to the current track plus the next five tracks to prevent runaway queue growth in dev sessions. * chore(analysis): remove unused loudness prefetch parameter Drop the now-unused incoming-tracks parameter from the loudness prefetch helper and update internal call sites to match the current queue-window scheduling logic. * docs(changelog): document analysis queue control fix (#480) Add a short 1.46.0 Fixed entry describing stale backfill pruning, the current+5 loudness backfill window cap, and debug prune counters for diagnostics. * docs(contributors): add cucadmuh entry for PR #480 Logs the analysis-queue prune + loudness backfill window cap in the Settings → System → Contributors list.
This commit is contained in:
+39
-15
@@ -1110,6 +1110,14 @@ async function runRefreshLoudnessForTrack(trackId: string, syncEngine: boolean):
|
||||
if (auth.normalizationEngine === 'loudness'
|
||||
&& !analysisBackfillInFlightByTrackId[trackId]
|
||||
&& attempts < MAX_BACKFILL_ATTEMPTS_PER_TRACK) {
|
||||
if (!isTrackInsideLoudnessBackfillWindow(trackId)) {
|
||||
emitNormalizationDebug('backfill:skipped-outside-window', {
|
||||
trackId,
|
||||
queueIndex: usePlayerStore.getState().queueIndex,
|
||||
aheadWindow: LOUDNESS_BACKFILL_WINDOW_AHEAD,
|
||||
});
|
||||
return;
|
||||
}
|
||||
analysisBackfillInFlightByTrackId[trackId] = true;
|
||||
analysisBackfillAttemptsByTrackId[trackId] = attempts + 1;
|
||||
const url = buildStreamUrl(trackId);
|
||||
@@ -1159,25 +1167,41 @@ async function runRefreshLoudnessForTrack(trackId: string, syncEngine: boolean):
|
||||
}
|
||||
|
||||
/** After bulk enqueue, warm loudness cache so gapless `audio_chain_preload` sees real gain, not only startup trim. */
|
||||
const LOUDNESS_PREFETCH_MAX_ENQUEUED_IDS = 40;
|
||||
const LOUDNESS_BACKFILL_WINDOW_AHEAD = 5;
|
||||
|
||||
function isTrackInsideLoudnessBackfillWindow(trackId: string): boolean {
|
||||
if (!trackId) return false;
|
||||
const state = usePlayerStore.getState();
|
||||
const currentId = state.currentTrack?.id;
|
||||
if (currentId === trackId) return true;
|
||||
if (state.queue.length === 0) return false;
|
||||
const start = Math.max(0, state.queueIndex + 1);
|
||||
const end = Math.min(state.queue.length, start + LOUDNESS_BACKFILL_WINDOW_AHEAD);
|
||||
for (let i = start; i < end; i++) {
|
||||
if (state.queue[i]?.id === trackId) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function collectLoudnessBackfillWindowTrackIds(queue: Track[], queueIndex: number, currentTrack: Track | null): string[] {
|
||||
const ids = new Set<string>();
|
||||
if (currentTrack?.id) ids.add(currentTrack.id);
|
||||
const start = Math.max(0, queueIndex + 1);
|
||||
const end = Math.min(queue.length, start + LOUDNESS_BACKFILL_WINDOW_AHEAD);
|
||||
for (let i = start; i < end; i++) {
|
||||
const tid = queue[i]?.id;
|
||||
if (tid) ids.add(tid);
|
||||
}
|
||||
return Array.from(ids);
|
||||
}
|
||||
|
||||
function prefetchLoudnessForEnqueuedTracks(
|
||||
incoming: Track[],
|
||||
mergedQueue: Track[],
|
||||
queueIndex: number,
|
||||
) {
|
||||
if (useAuthStore.getState().normalizationEngine !== 'loudness') return;
|
||||
const ids = new Set<string>();
|
||||
const next = mergedQueue[queueIndex + 1];
|
||||
if (next?.id) ids.add(next.id);
|
||||
let n = 0;
|
||||
for (const t of incoming) {
|
||||
if (n >= LOUDNESS_PREFETCH_MAX_ENQUEUED_IDS) break;
|
||||
if (t?.id) {
|
||||
ids.add(t.id);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
const currentTrack = usePlayerStore.getState().currentTrack;
|
||||
const ids = collectLoudnessBackfillWindowTrackIds(mergedQueue, queueIndex, currentTrack);
|
||||
for (const id of ids) {
|
||||
void refreshLoudnessForTrack(id, { syncPlayingEngine: false });
|
||||
}
|
||||
@@ -3203,7 +3227,7 @@ export const usePlayerStore = create<PlayerState>()(
|
||||
...state.queue.slice(firstAutoIdx),
|
||||
];
|
||||
syncQueueToServer(newQueue, state.currentTrack, state.currentTime);
|
||||
prefetchLoudnessForEnqueuedTracks(tracks, newQueue, state.queueIndex);
|
||||
prefetchLoudnessForEnqueuedTracks(newQueue, state.queueIndex);
|
||||
return { queue: newQueue };
|
||||
});
|
||||
},
|
||||
@@ -3252,7 +3276,7 @@ export const usePlayerStore = create<PlayerState>()(
|
||||
? state.queueIndex + tracks.length
|
||||
: state.queueIndex;
|
||||
syncQueueToServer(newQueue, state.currentTrack, state.currentTime);
|
||||
prefetchLoudnessForEnqueuedTracks(tracks, newQueue, newQueueIndex);
|
||||
prefetchLoudnessForEnqueuedTracks(newQueue, newQueueIndex);
|
||||
return { queue: newQueue, queueIndex: newQueueIndex };
|
||||
});
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user