Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Commit bd47bbd

Browse files
committed
fix telemetry in browser extension comlink
- Need to just call recordEvent instead of pass the entire TelemetryRecorder object across the Comlink interface. - Comlink's `Remote<...>` generic type struggles with the generics on the `TelemetryRecorder.recordEvent`, so just use strings.
1 parent e60d3f5 commit bd47bbd

File tree

6 files changed

+32
-31
lines changed

6 files changed

+32
-31
lines changed

client/browser/BUILD.bazel

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ ts_project(
206206
"src/shared/platform/inlineExtensionsService.ts",
207207
"src/shared/platform/ports.ts",
208208
"src/shared/platform/settings.ts",
209-
"src/shared/platform/worker.ts",
210209
"src/shared/polyfills.ts",
211210
"src/shared/repo/backend.tsx",
212211
"src/shared/repo/index.tsx",

client/shared/src/api/client/mainthread-api.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { type Remote, proxy } from 'comlink'
2-
import { type Unsubscribable, Subscription, from, of, lastValueFrom, ReplaySubject } from 'rxjs'
2+
import { type Unsubscribable, from, lastValueFrom, of, ReplaySubject, Subscription } from 'rxjs'
33
import { share, switchMap } from 'rxjs/operators'
44

55
import { logger } from '@sourcegraph/common'
@@ -141,7 +141,7 @@ export const initMainThreadAPI = (
141141
return proxySubscribable(of([]))
142142
},
143143
logEvent: (eventName, eventProperties) => platformContext.telemetryService?.log(eventName, eventProperties),
144-
getTelemetryRecorder: () => platformContext.telemetryRecorder,
144+
recordEvent: platformContext.telemetryRecorder.recordEvent as MainThreadAPI['recordEvent'],
145145
logExtensionMessage: (...data) => logger.log(...data),
146146
}
147147

client/shared/src/api/contract.ts

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
import type { Remote, ProxyMarked } from 'comlink'
1+
import type { ProxyMarked, Remote } from 'comlink'
22
import type { Unsubscribable } from 'rxjs'
33

44
import type {
55
Contributions,
66
Evaluated,
7+
HoverMerged,
78
Raw,
89
TextDocumentPositionParameters,
9-
HoverMerged,
1010
} from '@sourcegraph/client-api'
1111
import type { MaybeLoadingResult } from '@sourcegraph/codeintellify'
1212
import type * as clientType from '@sourcegraph/extension-api-types'
1313
import type { GraphQLResult } from '@sourcegraph/http-client'
14+
import type { KnownKeys, TelemetryEventParameters } from '@sourcegraph/telemetry'
1415

1516
import type { DocumentHighlight, ReferenceContext } from '../codeintel/legacy-extensions/api'
1617
import type { Occurrence } from '../codeintel/scip'
1718
import type { ConfiguredExtension } from '../extensions/extension'
1819
import type { SettingsCascade } from '../settings/settings'
19-
import type { TelemetryV2Props } from '../telemetry'
2020

2121
import type { SettingsEdit } from './client/services/settings'
2222
import type { ExecutableExtension } from './extension/activation'
@@ -75,7 +75,6 @@ export interface FlatExtensionHostAPI extends CodeIntelExtensionHostAPI {
7575
/**
7676
* Sets the given context keys and values.
7777
* If a value is `null`, the context key is removed.
78-
*
7978
* @param update Object with context keys as values
8079
*/
8180
updateContext: (update: { [k: string]: unknown }) => void
@@ -89,7 +88,6 @@ export interface FlatExtensionHostAPI extends CodeIntelExtensionHostAPI {
8988
/**
9089
* Returns an observable that emits all contributions (merged) evaluated in the current model
9190
* (with the optional scope). It emits whenever there is any change.
92-
*
9391
* @template T Extra allowed property value types for the {@link Context} value. See
9492
* {@link Context}'s `T` type parameter for more information.
9593
* @param scope The scope in which contributions are fetched. A scope can be a sub-component of
@@ -111,7 +109,6 @@ export interface FlatExtensionHostAPI extends CodeIntelExtensionHostAPI {
111109

112110
/**
113111
* Add a viewer.
114-
*
115112
* @param viewer The description of the viewer to add.
116113
* @returns The added code viewer (which must be passed as the first argument to other
117114
* viewer methods to operate on this viewer).
@@ -125,7 +122,6 @@ export interface FlatExtensionHostAPI extends CodeIntelExtensionHostAPI {
125122

126123
/**
127124
* Sets the selections for a CodeEditor.
128-
*
129125
* @param codeEditor The editor for which to set the selections.
130126
* @param selections The new selections to apply.
131127
* @throws if no editor exists with the given editor ID.
@@ -136,7 +132,6 @@ export interface FlatExtensionHostAPI extends CodeIntelExtensionHostAPI {
136132
/**
137133
* Removes a viewer.
138134
* Also removes the corresponding model if no other viewer is referencing it.
139-
*
140135
* @param viewer The viewer to remove.
141136
*/
142137
removeViewer(viewer: ViewerId): void
@@ -176,15 +171,29 @@ export interface MainThreadAPI {
176171

177172
/**
178173
* Log an event (by sending it to the server).
179-
*
180-
* @deprecated use getTelemetryRecorder().recordEvent instead
174+
* @deprecated use {@link MainThreadAPI.recordEvent} instead
181175
*/
182176
logEvent: (eventName: string, eventProperties?: any) => void
183177

184178
/**
185-
* Get a TelemetryRecorder for recording telemetry events to the server.
179+
* Record a telemetry event.
180+
*
181+
* The type signature should be kept in sync with {@link TelemetryRecorder.recordEvent}.
186182
*/
187-
getTelemetryRecorder: () => TelemetryV2Props['telemetryRecorder']
183+
recordEvent: (
184+
feature: string,
185+
action: string,
186+
parameters?: TelemetryEventParameters<
187+
KnownKeys<
188+
string,
189+
{
190+
[key in string]: number
191+
}
192+
>,
193+
string,
194+
string
195+
>
196+
) => void
188197

189198
/**
190199
* Log messages from extensions in the main thread. Makes it easier to debug extensions for applications

client/shared/src/api/extension/activation.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { catchError, concatMap, distinctUntilChanged, first, map, switchMap, tap
44
import type sourcegraph from 'sourcegraph'
55

66
import type { Contributions } from '@sourcegraph/client-api'
7-
import { asError, isErrorLike, hashCode, logger } from '@sourcegraph/common'
7+
import { asError, hashCode, isErrorLike, logger } from '@sourcegraph/common'
88

99
import {
1010
type ConfiguredExtension,
@@ -66,18 +66,17 @@ const DEPRECATED_EXTENSION_IDS = new Set(['sourcegraph/code-stats-insights', 'so
6666

6767
export function activateExtensions(
6868
state: Pick<ExtensionHostState, 'activeExtensions' | 'contributions' | 'haveInitialExtensionsLoaded' | 'settings'>,
69-
mainAPI: Remote<Pick<MainThreadAPI, 'logEvent' | 'getTelemetryRecorder'>>,
69+
mainAPI: Remote<Pick<MainThreadAPI, 'logEvent' | 'recordEvent'>>,
7070
createExtensionAPI: (extensionID: string) => typeof sourcegraph,
71-
mainThreadAPIInitializations: Observable<boolean>,
7271
/**
7372
* Function that activates an extension.
7473
* Returns a promise that resolves once the extension is activated.
75-
* */
74+
*/
7675
activate = activateExtension,
7776
/**
7877
* Function that de-activates an extension.
7978
* Returns a promise that resolves once the extension is de-activated.
80-
* */
79+
*/
8180
deactivate = deactivateExtension
8281
): Subscription {
8382
const previouslyActivatedExtensions = new Set<string>()
@@ -168,8 +167,7 @@ export function activateExtensions(
168167
.catch(() => {
169168
// noop
170169
})
171-
const telemetryRecorder = await mainAPI.getTelemetryRecorder()
172-
telemetryRecorder.recordEvent('blob.extension', 'activate', {
170+
mainAPI.recordEvent('blob.extension', 'activate', {
173171
privateMetadata: { extensionID: telemetryExtensionID },
174172
})
175173
} catch (error) {
@@ -365,7 +363,6 @@ export interface ExecutableExtension extends Pick<ConfiguredExtension, 'id' | 'm
365363
*
366364
* Because `require` is replaced on each extension activation with the API created for that extension,
367365
* the API can only be imported once to prevent extensions importing APIs created for other extensions.
368-
*
369366
* @param extensionAPI The extension API instance for the extension to be activated.
370367
* @throws error to give extension authors feedback if they try to import an API instance that was
371368
* already imported (e.g. if they asynchronously import the extension API and the current `require` was

client/shared/src/api/extension/extensionHost.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ export interface InitData {
3535
*
3636
* It expects to receive a message containing {@link InitData} from the client application as the
3737
* first message.
38-
*
3938
* @param endpoints The endpoints to the client.
4039
* @returns An unsubscribable to terminate the extension host.
4140
*/
@@ -74,7 +73,6 @@ export function startExtensionHost(
7473
*
7574
* The extension API is made globally available to all requires/imports of the "sourcegraph" module
7675
* by other scripts running in the same JavaScript context.
77-
*
7876
* @param endpoints The endpoints to the client.
7977
* @param initData The information to initialize this extension host.
8078
* @returns An unsubscribable to terminate the extension host.
@@ -137,7 +135,7 @@ function createExtensionAndExtensionHostAPIs(
137135
const createExtensionAPI = createExtensionAPIFactory(extensionHostState, proxy, initData)
138136

139137
// Activate extensions. Create extension APIs on extension activation.
140-
subscription.add(activateExtensions(extensionHostState, proxy, createExtensionAPI, mainThreadAPIInitializations))
138+
subscription.add(activateExtensions(extensionHostState, proxy, createExtensionAPI))
141139

142140
// Observe settings and update active loggers state
143141
subscription.add(setActiveLoggers(extensionHostState))

client/shared/src/api/extension/test/activation.test.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { BehaviorSubject, firstValueFrom, of } from 'rxjs'
1+
import { BehaviorSubject, firstValueFrom } from 'rxjs'
22
import { filter, first } from 'rxjs/operators'
33
import sinon from 'sinon'
44
import type sourcegraph from 'sourcegraph'
@@ -18,9 +18,9 @@ describe('Extension activation', () => {
1818
it('logs events for activated extensions', async () => {
1919
const logEvent = sinon.spy()
2020

21-
const mockMain = pretendRemote<Pick<MainThreadAPI, 'logEvent' | 'getTelemetryRecorder'>>({
21+
const mockMain = pretendRemote<Pick<MainThreadAPI, 'logEvent' | 'recordEvent'>>({
2222
logEvent,
23-
getTelemetryRecorder: () => noOpTelemetryRecorder,
23+
recordEvent: noOpTelemetryRecorder.recordEvent as MainThreadAPI['recordEvent'],
2424
})
2525

2626
const FIXTURE_EXTENSION: ExecutableExtension = {
@@ -53,8 +53,6 @@ describe('Extension activation', () => {
5353
function createExtensionAPI() {
5454
return {} as typeof sourcegraph
5555
},
56-
of(true),
57-
noopPromise,
5856
noopPromise
5957
)
6058

0 commit comments

Comments
 (0)