mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 14:35:41 +00:00
fix(analysis): native library backfill coordinator for advanced strategy (#881)
* feat(analysis): native library backfill coordinator for advanced strategy Move advanced analytics scheduling from the webview loop into a Rust background worker (configure + spawn_blocking batch/enqueue), matching cover backfill. Scan hash+BPM gap tracks instead of the full library; suppress low-priority analysis UI events; limit loudness refresh IPC to the playback window. * fix(analysis): flat backfill configure IPC and restore probe track-perf Use flattened Tauri args like cover backfill so release/prod invoke works; keep emitting analysis:track-perf for library low-priority work so Performance Probe tpm/last-track stats update while waveform/enrichment UI events stay suppressed. * chore(analysis): fix clippy and drop duplicate TS backfill policy Allow too_many_arguments on library_analysis_backfill_configure for CI; remove unused frontend batch API and TS watermark helpers now owned in Rust; clarify analysis_emits_ui_events comment for low-priority track-perf. * docs: CHANGELOG and credits for PR #881 native analysis backfill
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
//! Library analysis backfill queue watermark — native coordinator (spec: Settings → Library).
|
||||
|
||||
pub const LIBRARY_BACKLOG_DEPTH_MULTIPLIER: u32 = 3;
|
||||
pub const LIBRARY_BACKLOG_MIN: u32 = 8;
|
||||
pub const LIBRARY_BACKLOG_MAX: u32 = 240;
|
||||
pub const LIBRARY_ANALYSIS_BACKFILL_BATCH_SIZE: u32 = 20;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct PipelineBacklogCounts {
|
||||
pub http_queued: u32,
|
||||
pub http_download_active: u32,
|
||||
pub cpu_queued: u32,
|
||||
pub cpu_decode_active: u32,
|
||||
}
|
||||
|
||||
impl PipelineBacklogCounts {
|
||||
pub fn total(self) -> u32 {
|
||||
self.http_queued
|
||||
.saturating_add(self.http_download_active)
|
||||
.saturating_add(self.cpu_queued)
|
||||
.saturating_add(self.cpu_decode_active)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compute_library_backfill_target_depth(workers: u32) -> u32 {
|
||||
let w = workers.max(1);
|
||||
(w * LIBRARY_BACKLOG_DEPTH_MULTIPLIER).clamp(LIBRARY_BACKLOG_MIN, LIBRARY_BACKLOG_MAX)
|
||||
}
|
||||
|
||||
pub fn library_backfill_needs_top_up(counts: PipelineBacklogCounts, workers: u32) -> bool {
|
||||
counts.total() < compute_library_backfill_target_depth(workers)
|
||||
}
|
||||
|
||||
pub fn library_backfill_top_up_limit(counts: PipelineBacklogCounts, workers: u32) -> u32 {
|
||||
let target = compute_library_backfill_target_depth(workers);
|
||||
let deficit = target.saturating_sub(counts.total());
|
||||
if deficit == 0 {
|
||||
return 0;
|
||||
}
|
||||
deficit.min(LIBRARY_ANALYSIS_BACKFILL_BATCH_SIZE)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn target_depth_uses_floor_and_cap() {
|
||||
assert_eq!(compute_library_backfill_target_depth(1), 8);
|
||||
assert_eq!(compute_library_backfill_target_depth(4), 12);
|
||||
assert_eq!(compute_library_backfill_target_depth(100), 240);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn top_up_when_backlog_below_target() {
|
||||
let counts = PipelineBacklogCounts {
|
||||
http_queued: 2,
|
||||
http_download_active: 1,
|
||||
..Default::default()
|
||||
};
|
||||
assert!(library_backfill_needs_top_up(counts, 8));
|
||||
assert_eq!(library_backfill_top_up_limit(counts, 8), 20);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user