Skip to content

Commit d55dd13

Browse files
Add back posthog search_finished event
1 parent 9c9b6b9 commit d55dd13

File tree

3 files changed

+79
-44
lines changed

3 files changed

+79
-44
lines changed

packages/web/src/app/[domain]/search/components/searchResultsPage.tsx

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { CodePreviewPanel } from "./codePreviewPanel";
3232
import { FilterPanel } from "./filterPanel";
3333
import { useFilteredMatches } from "./filterPanel/useFilterMatches";
3434
import { SearchResultsPanel, SearchResultsPanelHandle } from "./searchResultsPanel";
35+
import useCaptureEvent from "@/hooks/useCaptureEvent";
3536

3637
interface SearchResultsPageProps {
3738
searchQuery: string;
@@ -50,6 +51,7 @@ export const SearchResultsPage = ({
5051
const { setSearchHistory } = useSearchHistory();
5152
const domain = useDomain();
5253
const { toast } = useToast();
54+
const captureEvent = useCaptureEvent();
5355

5456
// Encodes the number of matches to return in the search response.
5557
const _maxMatchCount = parseInt(useNonEmptyQueryParam(SearchQueryParams.matches) ?? `${defaultMaxMatchCount}`);
@@ -59,7 +61,8 @@ export const SearchResultsPage = ({
5961
error,
6062
files,
6163
repoInfo,
62-
durationMs,
64+
timeToSearchCompletionMs,
65+
timeToFirstSearchResultMs,
6366
isStreaming,
6467
numMatches,
6568
isExhaustive,
@@ -98,40 +101,52 @@ export const SearchResultsPage = ({
98101
])
99102
}, [searchQuery, setSearchHistory]);
100103

101-
// @todo: capture search stats on completion.
102-
// useEffect(() => {
103-
// if (!searchResponse) {
104-
// return;
105-
// }
104+
useEffect(() => {
105+
if (isStreaming || !stats) {
106+
return;
107+
}
106108

107-
// const fileLanguages = searchResponse.files?.map(file => file.language) || [];
109+
const fileLanguages = files.map(file => file.language) || [];
108110

109-
// captureEvent("search_finished", {
110-
// durationMs: searchResponse.totalClientSearchDurationMs,
111-
// fileCount: searchResponse.stats.fileCount,
112-
// matchCount: searchResponse.stats.totalMatchCount,
113-
// actualMatchCount: searchResponse.stats.actualMatchCount,
114-
// filesSkipped: searchResponse.stats.filesSkipped,
115-
// contentBytesLoaded: searchResponse.stats.contentBytesLoaded,
116-
// indexBytesLoaded: searchResponse.stats.indexBytesLoaded,
117-
// crashes: searchResponse.stats.crashes,
118-
// shardFilesConsidered: searchResponse.stats.shardFilesConsidered,
119-
// filesConsidered: searchResponse.stats.filesConsidered,
120-
// filesLoaded: searchResponse.stats.filesLoaded,
121-
// shardsScanned: searchResponse.stats.shardsScanned,
122-
// shardsSkipped: searchResponse.stats.shardsSkipped,
123-
// shardsSkippedFilter: searchResponse.stats.shardsSkippedFilter,
124-
// ngramMatches: searchResponse.stats.ngramMatches,
125-
// ngramLookups: searchResponse.stats.ngramLookups,
126-
// wait: searchResponse.stats.wait,
127-
// matchTreeConstruction: searchResponse.stats.matchTreeConstruction,
128-
// matchTreeSearch: searchResponse.stats.matchTreeSearch,
129-
// regexpsConsidered: searchResponse.stats.regexpsConsidered,
130-
// flushReason: searchResponse.stats.flushReason,
131-
// fileLanguages,
132-
// });
133-
// }, [captureEvent, searchQuery, searchResponse]);
111+
console.debug('timeToFirstSearchResultMs:', timeToFirstSearchResultMs);
112+
console.debug('timeToSearchCompletionMs:', timeToSearchCompletionMs);
134113

114+
captureEvent("search_finished", {
115+
durationMs: timeToSearchCompletionMs,
116+
timeToSearchCompletionMs,
117+
timeToFirstSearchResultMs,
118+
fileCount: stats.fileCount,
119+
matchCount: stats.totalMatchCount,
120+
actualMatchCount: stats.actualMatchCount,
121+
filesSkipped: stats.filesSkipped,
122+
contentBytesLoaded: stats.contentBytesLoaded,
123+
indexBytesLoaded: stats.indexBytesLoaded,
124+
crashes: stats.crashes,
125+
shardFilesConsidered: stats.shardFilesConsidered,
126+
filesConsidered: stats.filesConsidered,
127+
filesLoaded: stats.filesLoaded,
128+
shardsScanned: stats.shardsScanned,
129+
shardsSkipped: stats.shardsSkipped,
130+
shardsSkippedFilter: stats.shardsSkippedFilter,
131+
ngramMatches: stats.ngramMatches,
132+
ngramLookups: stats.ngramLookups,
133+
wait: stats.wait,
134+
matchTreeConstruction: stats.matchTreeConstruction,
135+
matchTreeSearch: stats.matchTreeSearch,
136+
regexpsConsidered: stats.regexpsConsidered,
137+
flushReason: stats.flushReason,
138+
fileLanguages,
139+
isSearchExhaustive: isExhaustive,
140+
});
141+
}, [
142+
captureEvent,
143+
files,
144+
isStreaming,
145+
isExhaustive,
146+
stats,
147+
timeToSearchCompletionMs,
148+
timeToFirstSearchResultMs,
149+
]);
135150

136151
const onLoadMoreResults = useCallback(() => {
137152
const url = createPathWithQueryParams(`/${domain}/search`,
@@ -170,7 +185,7 @@ export const SearchResultsPage = ({
170185
onLoadMoreResults={onLoadMoreResults}
171186
numMatches={numMatches}
172187
repoInfo={repoInfo}
173-
searchDurationMs={durationMs}
188+
searchDurationMs={timeToSearchCompletionMs}
174189
isStreaming={isStreaming}
175190
searchStats={stats}
176191
isMoreResultsButtonVisible={!isExhaustive}

packages/web/src/app/[domain]/search/useStreamedSearch.ts

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ interface CacheEntry {
88
files: SearchResultFile[];
99
repoInfo: Record<number, RepositoryInfo>;
1010
numMatches: number;
11-
durationMs: number;
11+
timeToSearchCompletionMs: number;
12+
timeToFirstSearchResultMs: number;
1213
timestamp: number;
1314
isExhaustive: boolean;
1415
}
@@ -39,7 +40,8 @@ export const useStreamedSearch = ({ query, matches, contextLines, whole, isRegex
3940
error: Error | null,
4041
files: SearchResultFile[],
4142
repoInfo: Record<number, RepositoryInfo>,
42-
durationMs: number,
43+
timeToSearchCompletionMs: number,
44+
timeToFirstSearchResultMs: number,
4345
numMatches: number,
4446
stats?: SearchStats,
4547
}>({
@@ -48,7 +50,8 @@ export const useStreamedSearch = ({ query, matches, contextLines, whole, isRegex
4850
error: null,
4951
files: [],
5052
repoInfo: {},
51-
durationMs: 0,
53+
timeToSearchCompletionMs: 0,
54+
timeToFirstSearchResultMs: 0,
5255
numMatches: 0,
5356
stats: undefined,
5457
});
@@ -94,7 +97,8 @@ export const useStreamedSearch = ({ query, matches, contextLines, whole, isRegex
9497
error: null,
9598
files: cachedEntry.files,
9699
repoInfo: cachedEntry.repoInfo,
97-
durationMs: cachedEntry.durationMs,
100+
timeToSearchCompletionMs: cachedEntry.timeToSearchCompletionMs,
101+
timeToFirstSearchResultMs: cachedEntry.timeToFirstSearchResultMs,
98102
numMatches: cachedEntry.numMatches,
99103
});
100104
return;
@@ -106,7 +110,8 @@ export const useStreamedSearch = ({ query, matches, contextLines, whole, isRegex
106110
error: null,
107111
files: [],
108112
repoInfo: {},
109-
durationMs: 0,
113+
timeToSearchCompletionMs: 0,
114+
timeToFirstSearchResultMs: 0,
110115
numMatches: 0,
111116
});
112117

@@ -138,6 +143,7 @@ export const useStreamedSearch = ({ query, matches, contextLines, whole, isRegex
138143
const reader = response.body.getReader();
139144
const decoder = new TextDecoder();
140145
let buffer = '';
146+
let numMessagesProcessed = 0;
141147

142148
while (true as boolean) {
143149
const { done, value } = await reader.read();
@@ -175,6 +181,7 @@ export const useStreamedSearch = ({ query, matches, contextLines, whole, isRegex
175181
}
176182

177183
const response: StreamedSearchResponse = JSON.parse(data);
184+
const isFirstMessage = numMessagesProcessed === 0;
178185
switch (response.type) {
179186
case 'chunk':
180187
setState(prev => ({
@@ -191,33 +198,42 @@ export const useStreamedSearch = ({ query, matches, contextLines, whole, isRegex
191198
}, {} as Record<number, RepositoryInfo>),
192199
},
193200
numMatches: prev.numMatches + response.stats.actualMatchCount,
201+
...(isFirstMessage ? {
202+
timeToFirstSearchResultMs: performance.now() - startTime,
203+
} : {}),
194204
}));
195205
break;
196206
case 'final':
197207
setState(prev => ({
198208
...prev,
199209
isExhaustive: response.isSearchExhaustive,
200210
stats: response.accumulatedStats,
211+
...(isFirstMessage ? {
212+
timeToFirstSearchResultMs: performance.now() - startTime,
213+
} : {}),
201214
}));
202215
break;
203216
}
217+
218+
numMessagesProcessed++;
204219
}
205220
}
206221

207-
const durationMs = performance.now() - startTime;
222+
const timeToSearchCompletionMs = performance.now() - startTime;
208223
setState(prev => {
209224
// Cache the final results after the stream has completed.
210225
searchCache.set(cacheKey, {
211226
files: prev.files,
212227
repoInfo: prev.repoInfo,
213228
isExhaustive: prev.isExhaustive,
214229
numMatches: prev.numMatches,
215-
durationMs,
230+
timeToFirstSearchResultMs: prev.timeToFirstSearchResultMs,
231+
timeToSearchCompletionMs,
216232
timestamp: Date.now(),
217233
});
218234
return {
219235
...prev,
220-
durationMs,
236+
timeToSearchCompletionMs,
221237
isStreaming: false,
222238
}
223239
});
@@ -229,11 +245,11 @@ export const useStreamedSearch = ({ query, matches, contextLines, whole, isRegex
229245

230246
console.error(error);
231247
Sentry.captureException(error);
232-
const durationMs = performance.now() - startTime;
248+
const timeToSearchCompletionMs = performance.now() - startTime;
233249
setState(prev => ({
234250
...prev,
235251
isStreaming: false,
236-
durationMs,
252+
timeToSearchCompletionMs,
237253
error: error as Error,
238254
}));
239255
}

packages/web/src/lib/posthogEvents.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ export type PosthogEventMap = {
55
contentBytesLoaded: number,
66
indexBytesLoaded: number,
77
crashes: number,
8+
/** @deprecated: use timeToFirstSearchResultMs and timeToSearchCompletionMs instead */
89
durationMs: number,
10+
timeToFirstSearchResultMs: number,
11+
timeToSearchCompletionMs: number,
912
fileCount: number,
1013
shardFilesConsidered: number,
1114
filesConsidered: number,
@@ -23,7 +26,8 @@ export type PosthogEventMap = {
2326
matchTreeSearch: number,
2427
regexpsConsidered: number,
2528
flushReason: number,
26-
fileLanguages: string[]
29+
fileLanguages: string[],
30+
isSearchExhaustive: boolean
2731
},
2832
share_link_created: {},
2933
////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)