Files
Psychotoxical-psysonic/src/hooks/useLibraryAnalysisBackfill.ts
T
cucadmuh b24a7fc5cb 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
2026-05-28 10:49:31 +03:00

80 lines
2.5 KiB
TypeScript

import { useEffect } from 'react';
import {
analysisSetPipelineParallelism,
libraryAnalysisBackfillConfigure,
} from '../api/analysis';
import { librarySqlServerId } from '../api/coverCache';
import { useAuthStore } from '../store/authStore';
import { useAnalysisStrategyStore } from '../store/analysisStrategyStore';
import { DEFAULT_ADVANCED_PARALLELISM } from '../utils/library/analysisStrategy';
import { serverIndexKeyForProfile } from '../utils/server/serverIndexKey';
const DISABLED_CONFIGURE = {
enabled: false,
serverIndexKey: '',
libraryServerId: '',
serverUrl: '',
username: '',
password: '',
workers: DEFAULT_ADVANCED_PARALLELISM,
} as const;
/**
* Advanced analytics strategy: native coordinator in Rust (see `library_analysis_backfill`).
* Webview only passes session + worker count — no planning loop or batch IPC.
*/
export function useLibraryAnalysisBackfill(enabled = true): void {
const activeServerId = useAuthStore(s => s.activeServerId);
const server = useAuthStore(s =>
s.activeServerId ? s.servers.find(srv => srv.id === s.activeServerId) : undefined,
);
const getBaseUrl = useAuthStore(s => s.getBaseUrl);
const strategy = useAnalysisStrategyStore(s => s.getStrategyForServer(activeServerId));
const advancedParallelism = useAnalysisStrategyStore(
s => s.getAdvancedParallelismForServer(activeServerId),
);
useEffect(() => {
if (!enabled) return;
const workers =
strategy === 'advanced' ? advancedParallelism : DEFAULT_ADVANCED_PARALLELISM;
void analysisSetPipelineParallelism(workers).catch(() => {});
}, [strategy, advancedParallelism, enabled]);
useEffect(() => {
const disable = () => {
void libraryAnalysisBackfillConfigure(DISABLED_CONFIGURE);
};
if (!enabled || strategy !== 'advanced' || !activeServerId || !server) {
disable();
return disable;
}
const indexKey = serverIndexKeyForProfile(server);
const baseUrl = getBaseUrl();
void libraryAnalysisBackfillConfigure({
enabled: true,
serverIndexKey: indexKey,
libraryServerId: librarySqlServerId(activeServerId),
serverUrl: baseUrl,
username: server.username,
password: server.password,
workers: advancedParallelism,
}).catch(() => {
/* coordinator optional; avoid unhandled rejection noise in release */
});
return disable;
}, [
enabled,
strategy,
activeServerId,
server?.url,
server?.username,
server?.password,
advancedParallelism,
getBaseUrl,
]);
}