mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2026-09-22 19:22:25 +01:00
fb250259ed
* perf: remove deprecated copilot feature, add ARM timeouts, fix race conditions - Remove entire QueryCopilot feature (~50 files deleted, ~30 files cleaned) - Remove CopilotConfigured and SampleDataLoaded metric phases - Fix DatabaseTreeRendered 76% stuck rate (remove one-shot guard in useMetricPhases) - Add 8s default timeout to ARM requests (AbortController-based) - Fix MSAL token forceRefresh (true -> false, use cache) - Add concurrency limit of 5 to collection loading in Explorer - Remove orphaned SampleDataClient.ts and queryCopilotSampleData.json - Clean up dead sampleDataConnectionInfo field from UserContext * Clean up copilot and optimize initialization * Clean up copilot and optimize initialization
64 lines
2.4 KiB
TypeScript
64 lines
2.4 KiB
TypeScript
import React from "react";
|
|
import MetricScenario from "./MetricEvents";
|
|
import { ApplicationMetricPhase, CommonMetricPhase } from "./ScenarioConfig";
|
|
import { scenarioMonitor } from "./ScenarioMonitor";
|
|
|
|
/**
|
|
* Completes the Interactive phase once the browser is ready to paint.
|
|
*
|
|
* Uses requestAnimationFrame with a setTimeout fallback. In foreground tabs rAF fires
|
|
* first (~16 ms) giving an accurate "browser painted" signal. In background tabs browsers
|
|
* suspend rAF indefinitely, so the setTimeout fallback (1 s) completes the phase instead —
|
|
* well within the 10 s scenario timeout — preventing false-negative unhealthy reports.
|
|
*/
|
|
export function useInteractive(scenario: MetricScenario, enabled = true) {
|
|
React.useEffect(() => {
|
|
if (!enabled) {
|
|
return undefined;
|
|
}
|
|
|
|
let completed = false;
|
|
const complete = () => {
|
|
if (completed) {
|
|
return;
|
|
}
|
|
completed = true;
|
|
cancelAnimationFrame(rafId);
|
|
clearTimeout(timeoutId);
|
|
scenarioMonitor.completePhase(scenario, CommonMetricPhase.Interactive);
|
|
};
|
|
|
|
const rafId = requestAnimationFrame(complete);
|
|
// Fallback for background tabs where rAF is suspended.
|
|
const timeoutId = setTimeout(complete, 1000);
|
|
|
|
return () => {
|
|
cancelAnimationFrame(rafId);
|
|
clearTimeout(timeoutId);
|
|
};
|
|
}, [scenario, enabled]);
|
|
}
|
|
|
|
/**
|
|
* Hook to manage DatabaseLoad scenario phase completions.
|
|
* Tracks tree rendering and completes Interactive phase.
|
|
* Only attempts to complete DatabaseTreeRendered if the database fetch was successful.
|
|
* Note: Scenario must be started before databases are fetched (in refreshExplorer).
|
|
*
|
|
* No one-shot guard is needed — completePhase is idempotent (ScenarioMonitor returns
|
|
* early if the phase hasn't been started yet, is already completed, or is already
|
|
* emitted). This lets the effect safely re-fire on every databaseTreeNodes change
|
|
* until the phase has actually been started via startPhase() in Explorer.tsx.
|
|
*/
|
|
export function useDatabaseLoadScenario(databaseTreeNodes: unknown[], fetchSucceeded: boolean) {
|
|
// Track DatabaseTreeRendered phase (only if fetch succeeded)
|
|
React.useEffect(() => {
|
|
if (fetchSucceeded) {
|
|
scenarioMonitor.completePhase(MetricScenario.DatabaseLoad, ApplicationMetricPhase.DatabaseTreeRendered);
|
|
}
|
|
}, [databaseTreeNodes, fetchSucceeded]);
|
|
|
|
// Track Interactive phase
|
|
useInteractive(MetricScenario.DatabaseLoad);
|
|
}
|