Skip to content

Commit e8cc021

Browse files
committed
extension/src: rename telemetry state starting to running
- The _state of telemetry reporter is reflecting whether an ongoing telemetry data write is happening. flush method set the _state to STARTING before calling vscgo to write telemetry data. Also the RUNNING state is not being referenced (safe to remove). However, RUNNING is more accurate compares to STARTING so I replace all STARTING appearance with RUNNING. - Replace comments with JSDoc, explain public methods of telemetry reporter class in more detail. For #3697 Change-Id: Iff696748b7550d5fb40853be99bb6054665b518a Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/660095 kokoro-CI: kokoro <[email protected]> Reviewed-by: Peter Weinberger <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 20e9536 commit e8cc021

File tree

1 file changed

+66
-21
lines changed

1 file changed

+66
-21
lines changed

extension/src/goTelemetry.ts

Lines changed: 66 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,25 @@ import * as cp from 'child_process';
1313
import { getWorkspaceFolderPath } from './util';
1414
import { toolExecutionEnvironment } from './goEnv';
1515

16-
// Name of the prompt telemetry command. This is also used to determine if the gopls instance supports telemetry.
17-
// Exported for testing.
16+
/**
17+
* Name of the prompt telemetry command. This is also used to determine if the
18+
* gopls instance supports telemetry.
19+
* Exported for testing.
20+
*/
1821
export const GOPLS_MAYBE_PROMPT_FOR_TELEMETRY = 'gopls.maybe_prompt_for_telemetry';
1922

20-
// Key for the global state that holds the very first time the telemetry-enabled gopls was observed.
21-
// Exported for testing.
23+
/**
24+
* Key for the global state that holds the very first time the telemetry-enabled
25+
* gopls was observed.
26+
* Exported for testing.
27+
*/
2228
export const TELEMETRY_START_TIME_KEY = 'telemetryStartTime';
2329

24-
// Run our encode/decode function for the Date object, to be defensive
25-
// from vscode Memento API behavior change.
26-
// Exported for testing.
30+
/**
31+
* Run our encode/decode function for the Date object, to be defensive from
32+
* vscode Memento API behavior change.
33+
* Exported for testing.
34+
*/
2735
export function recordTelemetryStartTime(storage: vscode.Memento, date: Date) {
2836
storage.update(TELEMETRY_START_TIME_KEY, date.toJSON());
2937
}
@@ -43,32 +51,57 @@ function readTelemetryStartTime(storage: vscode.Memento): Date | null {
4351
enum ReporterState {
4452
NOT_INITIALIZED,
4553
IDLE,
46-
STARTING,
4754
RUNNING
4855
}
4956

50-
// exported for testing.
57+
/**
58+
* Manages Go telemetry data and persists them to disk using a storage tool.
59+
*
60+
* **Usage:**
61+
* 1. Call `setTool(tool)` once, before any other methods.
62+
* 2. Call `add(key, value)` to add values associated with keys.
63+
* 3. Data is automatically flushed to disk periodically.
64+
* 4. To force an immediate flush, call `flush(true)`.
65+
*
66+
* **Example:**
67+
* ```typescript
68+
* const r = new TelemetryReporter();
69+
* r.setTool(vscgo);
70+
* r.add("count", 10);
71+
* r.add("count", 5);
72+
* r.flush(true); // Force a flush
73+
* ```
74+
*
75+
* Exported for testing.
76+
*/
5177
export class TelemetryReporter implements vscode.Disposable {
5278
private _state = ReporterState.NOT_INITIALIZED;
5379
private _counters: { [key: string]: number } = {};
5480
private _flushTimer: NodeJS.Timeout | undefined;
5581
private _tool = '';
5682
constructor(flushIntervalMs = 60_000, private counterFile: string = '') {
5783
if (flushIntervalMs > 0) {
58-
// periodically call flush.
84+
// Periodically call flush.
5985
this._flushTimer = setInterval(this.flush.bind(this), flushIntervalMs);
6086
}
6187
}
6288

89+
/**
90+
* Initializes the tool.
91+
* This method should be called once. Subsequent calls have no effect.
92+
*/
6393
public setTool(tool: string) {
64-
// allow only once.
94+
// Allow only once.
6595
if (tool === '' || this._state !== ReporterState.NOT_INITIALIZED) {
6696
return;
6797
}
6898
this._state = ReporterState.IDLE;
6999
this._tool = tool;
70100
}
71101

102+
/**
103+
* Adds a numeric value to a counter associated with the given key.
104+
*/
72105
public add(key: string, value: number) {
73106
if (value <= 0) {
74107
return;
@@ -77,16 +110,20 @@ export class TelemetryReporter implements vscode.Disposable {
77110
this._counters[key] = (this._counters[key] || 0) + value;
78111
}
79112

80-
// flush is called periodically (by the callback set up in the constructor)
81-
// or when the extension is deactivated (with force=true).
113+
/**
114+
* Flushes Go telemetry data.
115+
* * When `force` is true, telemetry is flushed immediately, bypassing the
116+
* IDLE state check.
117+
* * When `force` is false, telemetry is flushed only if the reporter is IDLE.
118+
*/
82119
public async flush(force = false) {
83120
// If flush runs with force=true, ignore the state and skip state update.
84121
if (!force && this._state !== ReporterState.IDLE) {
85122
// vscgo is not installed yet or is running. flush next time.
86123
return 0;
87124
}
88125
if (!force) {
89-
this._state = ReporterState.STARTING;
126+
this._state = ReporterState.RUNNING;
90127
}
91128
try {
92129
await this.writeGoTelemetry();
@@ -142,11 +179,13 @@ export class TelemetryReporter implements vscode.Disposable {
142179
clearInterval(this._flushTimer);
143180
}
144181
this._flushTimer = undefined;
145-
await this.flush(true); // flush any remaining data in buffer.
182+
await this.flush(true); // Flush any remaining data in buffer.
146183
}
147184
}
148185

149-
// global telemetryReporter instance.
186+
/**
187+
* Global telemetryReporter instance.
188+
*/
150189
export const telemetryReporter = new TelemetryReporter();
151190

152191
// TODO(hyangah): consolidate the list of all the telemetries and bucketting functions.
@@ -155,8 +194,10 @@ export function addTelemetryEvent(name: string, count: number) {
155194
telemetryReporter.add(name, count);
156195
}
157196

158-
// Go extension delegates most of the telemetry logic to gopls.
159-
// TelemetryService provides API to interact with gopls's telemetry.
197+
/**
198+
* Go extension delegates most of the telemetry logic to gopls.
199+
* TelemetryService provides API to interact with gopls's telemetry.
200+
*/
160201
export class TelemetryService {
161202
private active = false;
162203
constructor(
@@ -219,8 +260,10 @@ export class TelemetryService {
219260
}
220261
}
221262

222-
// Set telemetry env vars for gopls. See gopls/internal/server/prompt.go
223-
// TODO(hyangah): add an integration testing after gopls v0.17 becomes available.
263+
/**
264+
* Set telemetry env vars for gopls. See gopls/internal/server/prompt.go
265+
* TODO(hyangah): add an integration testing after gopls v0.17 becomes available.
266+
*/
224267
export function setTelemetryEnvVars(globalState: vscode.Memento, env: NodeJS.ProcessEnv) {
225268
if (!env['GOTELEMETRY_GOPLS_CLIENT_TOKEN']) {
226269
env['GOTELEMETRY_GOPLS_CLIENT_TOKEN'] = `${hashMachineID() + 1}`; // [1, 1000]
@@ -234,7 +277,9 @@ export function setTelemetryEnvVars(globalState: vscode.Memento, env: NodeJS.Pro
234277
}
235278
}
236279

237-
// Map vscode.env.machineId to an integer in [0, 1000).
280+
/**
281+
* Map vscode.env.machineId to an integer in [0, 1000).
282+
*/
238283
function hashMachineID(salt?: string): number {
239284
const hash = createHash('md5').update(`${vscode.env.machineId}${salt}`).digest('hex');
240285
return parseInt(hash.substring(0, 8), 16) % 1000;

0 commit comments

Comments
 (0)