Measure semantic activation refresh independently from download and idle time
This commit is contained in:
1 parent
9aae3f8216
commit
19d949fd13
6 files changed
+140
-22
No files matched your search
+28
-13
@@ -30,7 +30,11 @@ import {
|
||||
spanDepth,
|
||||
briefMs,
|
||||
} from "./search-performance";
|
||||
import type { MeasuredResponse, SearchLane } from "./search-performance";
|
||||
import type {
|
||||
MeasuredResponse,
|
||||
SearchLane,
|
||||
SearchRefreshTrigger,
|
||||
} from "./search-performance";
|
||||
import { displayPath } from "./path-display";
|
||||
import { ResultSelection } from "./selection-state";
|
||||
import {
|
||||
@@ -449,7 +453,7 @@ async function refreshSemanticStatus() {
|
||||
canSearchSemantically() &&
|
||||
latestSearch?.id === requestId
|
||||
)
|
||||
submitSearch(latestSearch, "hybrid");
|
||||
refreshIndexedSearch("semantic_activation");
|
||||
if (working || (!status.ready && !error)) queueSemanticRefresh();
|
||||
} catch (error) {
|
||||
element("semantic-status").textContent =
|
||||
@@ -1088,7 +1092,22 @@ function submitSearch(request: SearchRequest, lane: SearchLane) {
|
||||
(lane === "lexical" ? lexicalLane : hybridLane).submit(request);
|
||||
}
|
||||
|
||||
function refreshIndexedSearch() {
|
||||
function searchMeasurementContext() {
|
||||
return {
|
||||
model: semanticStatus?.worker_info?.model ?? null,
|
||||
device: semanticStatus?.worker_info?.device ?? null,
|
||||
runtime: semanticStatus?.worker_info?.runtime ?? null,
|
||||
threads: semanticStatus?.worker_info?.threads ?? null,
|
||||
dimensions: semanticStatus?.worker_info?.dimensions ?? null,
|
||||
semantic_ready: canSearchSemantically(),
|
||||
semantic_generation: semanticStatus?.generation ?? null,
|
||||
indexed_chunks: semanticStatus?.chunks ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
function refreshIndexedSearch(
|
||||
trigger: SearchRefreshTrigger = "filesystem_refresh",
|
||||
) {
|
||||
const previous = latestSearch;
|
||||
if (
|
||||
!previous ||
|
||||
@@ -1106,7 +1125,11 @@ function refreshIndexedSearch() {
|
||||
...previous,
|
||||
id: ++requestId,
|
||||
started: refreshStarted,
|
||||
measurement: previous.measurement.freshForRefresh(refreshStarted),
|
||||
measurement: previous.measurement.freshForRefresh(
|
||||
refreshStarted,
|
||||
trigger,
|
||||
searchMeasurementContext(),
|
||||
),
|
||||
};
|
||||
latestSearch = refreshed;
|
||||
submitSearch(refreshed, "lexical");
|
||||
@@ -1188,15 +1211,7 @@ async function search(inputAt = performance.now()) {
|
||||
inputAt,
|
||||
performance.now(),
|
||||
element<HTMLInputElement>("performance-toggle").checked,
|
||||
{
|
||||
model: semanticStatus?.worker_info?.model ?? null,
|
||||
device: semanticStatus?.worker_info?.device ?? null,
|
||||
runtime: semanticStatus?.worker_info?.runtime ?? null,
|
||||
threads: semanticStatus?.worker_info?.threads ?? null,
|
||||
dimensions: semanticStatus?.worker_info?.dimensions ?? null,
|
||||
semantic_ready: canSearchSemantically(),
|
||||
indexed_chunks: semanticStatus?.chunks ?? null,
|
||||
},
|
||||
searchMeasurementContext(),
|
||||
),
|
||||
};
|
||||
latestSearch = request;
|
||||
|
||||
@@ -17,6 +17,7 @@ export interface MeasuredResponse<T> {
|
||||
metrics: NativeMetrics;
|
||||
}
|
||||
export type SearchLane = "lexical" | "hybrid";
|
||||
export type SearchRefreshTrigger = "filesystem_refresh" | "semantic_activation";
|
||||
export interface AttemptStart {
|
||||
lane: SearchLane;
|
||||
startedAt: number;
|
||||
@@ -44,6 +45,7 @@ interface InputTimingSummary {
|
||||
|
||||
export class SearchMeasurement {
|
||||
private originalInput: Readonly<InputTimingSummary> | null = null;
|
||||
private trigger: "user_search" | SearchRefreshTrigger = "user_search";
|
||||
debug: boolean;
|
||||
inputAt: number;
|
||||
scheduledAt: number;
|
||||
@@ -74,9 +76,14 @@ export class SearchMeasurement {
|
||||
this.debug = debug;
|
||||
this.context = { ...context };
|
||||
}
|
||||
/** Filesystem updates are independent requests, not elapsed user idle time. */
|
||||
freshForRefresh(now: number): SearchMeasurement {
|
||||
const refreshed = new SearchMeasurement(now, now, this.debug, this.context);
|
||||
/** Background updates are independent requests, not elapsed user idle time. */
|
||||
freshForRefresh(
|
||||
now: number,
|
||||
trigger: SearchRefreshTrigger = "filesystem_refresh",
|
||||
context = this.context,
|
||||
): SearchMeasurement {
|
||||
const refreshed = new SearchMeasurement(now, now, this.debug, context);
|
||||
refreshed.trigger = trigger;
|
||||
// Preserve one fixed-size numeric snapshot, never an ancestor trace/history.
|
||||
// Pending responses on the old request cannot rewrite this snapshot.
|
||||
refreshed.originalInput = Object.freeze({
|
||||
@@ -165,7 +172,7 @@ export class SearchMeasurement {
|
||||
export() {
|
||||
return {
|
||||
version: 1,
|
||||
trigger: this.originalInput ? "filesystem_refresh" : "user_search",
|
||||
trigger: this.trigger,
|
||||
original_input: this.originalInput ? { ...this.originalInput } : null,
|
||||
context: this.context,
|
||||
clock_note:
|
||||
|
||||
Reference in new issue
Block a user