feat(perf): cover pipeline throughput (cpm) in performance probe (#945)

* feat(perf): cover pipeline throughput (cpm) in performance probe

Mirror the analysis pipeline's tpm for covers. A new coverPerfStore samples the
backfill `done` progress from cover:library-progress events and derives a rolling
one-minute covers-per-minute rate. Surfaced as a live diag in perfLiveStore, a
pinnable "Cover backfill" throughput card in the Monitor tab, and a cpm row in
the Cover pipeline overlay block.

* docs(changelog): note cover pipeline cpm metric (PR #945)

Add CHANGELOG entry and credits line for the cover-pipeline covers-per-minute
throughput metric in the Performance Probe.
This commit is contained in:
cucadmuh
2026-06-02 11:05:28 +03:00
committed by GitHub
parent 42aec6720c
commit c6df05e576
11 changed files with 279 additions and 4 deletions
+39
View File
@@ -0,0 +1,39 @@
import { useEffect } from 'react';
import { listen } from '@tauri-apps/api/event';
import { recordCoverProgress } from '../utils/perf/coverPerfStore';
type CoverLibraryProgressPayload = {
serverIndexKey?: string;
done?: number;
total?: number;
pending?: number;
};
/** Wire Rust `cover:library-progress` events into the cover perf store. */
export function useCoverPerfListener(active: boolean): void {
useEffect(() => {
if (!active) return;
let cancelled = false;
let unlisten: (() => void) | undefined;
void listen<CoverLibraryProgressPayload>('cover:library-progress', ({ payload }) => {
if (cancelled || typeof payload?.done !== 'number') return;
recordCoverProgress({
done: payload.done,
total: payload.total,
pending: payload.pending,
});
})
.then(fn => {
if (cancelled) {
fn();
return;
}
unlisten = fn;
})
.catch(() => {});
return () => {
cancelled = true;
unlisten?.();
};
}, [active]);
}
+15
View File
@@ -3,6 +3,7 @@ import { acquirePerfLivePoll, patchPerfLiveAnalysis } from '../utils/perf/perfLi
import { setPerfProbeTelemetryActive } from '../utils/perf/perfTelemetry';
import { useAnalysisPerfLast } from '../utils/perf/analysisPerfStore';
import { useAnalysisPerfListener } from './useAnalysisPerfListener';
import { useCoverPerfListener } from './useCoverPerfListener';
import {
getPerfProbeFlags,
subscribePerfProbeFlags,
@@ -31,14 +32,28 @@ function useNeedAnalysisTelemetry(perfProbeOpen: boolean, livePins: ReadonlySet<
);
}
function useNeedCoverTelemetry(perfProbeOpen: boolean, livePins: ReadonlySet<string>): boolean {
return useSyncExternalStore(
subscribePerfProbeFlags,
() => (
perfProbeOpen
|| getPerfProbeFlags().showCoverPerfOverlay
|| livePins.has('cover:cpm')
),
() => perfProbeOpen,
);
}
/** Wires Ctrl+Shift+D probe modal and shared live metric polling. */
export function useSidebarPerfProbe(): Result {
const [perfProbeOpen, setPerfProbeOpen] = useState(false);
const livePins = usePerfLiveOverlayPins();
const analysisLast = useAnalysisPerfLast();
const needAnalysis = useNeedAnalysisTelemetry(perfProbeOpen, livePins);
const needCover = useNeedCoverTelemetry(perfProbeOpen, livePins);
useAnalysisPerfListener(needAnalysis);
useCoverPerfListener(needCover);
useEffect(() => {
setPerfProbeTelemetryActive(perfProbeOpen);