Skip to content

Commit 2c2f382

Browse files
authored
Remove jedi memory telemetry (#15832)
1 parent ed196e8 commit 2c2f382

File tree

6 files changed

+10
-250
lines changed

6 files changed

+10
-250
lines changed

package-lock.json

+3-32
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

-1
Original file line numberDiff line numberDiff line change
@@ -2017,7 +2017,6 @@
20172017
"named-js-regexp": "^1.3.3",
20182018
"node-fetch": "^2.6.1",
20192019
"node-stream-zip": "^1.6.0",
2020-
"pidusage-tree": "^2.0.5",
20212020
"portfinder": "^1.0.25",
20222021
"reflect-metadata": "^0.1.12",
20232022
"request": "^2.87.0",

src/client/activation/jedi/languageServerProxy.ts

+4-85
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,18 @@ import {
1313
import { ChildProcess } from 'child_process';
1414
import { DeprecatePythonPath } from '../../common/experiments/groups';
1515
import { traceDecorators, traceError } from '../../common/logger';
16-
import {
17-
IConfigurationService,
18-
IExperimentsManager,
19-
IInterpreterPathService,
20-
IPythonSettings,
21-
Resource,
22-
} from '../../common/types';
16+
import { IExperimentsManager, IInterpreterPathService, Resource } from '../../common/types';
2317
import { swallowExceptions } from '../../common/utils/decorators';
2418
import { LanguageServerSymbolProvider } from '../../providers/symbolProvider';
2519
import { PythonEnvironment } from '../../pythonEnvironments/info';
26-
import { captureTelemetry, sendTelemetryEvent } from '../../telemetry';
20+
import { captureTelemetry } from '../../telemetry';
2721
import { EventName } from '../../telemetry/constants';
2822
import { ITestingService } from '../../testing/types';
2923
import { FileBasedCancellationStrategy } from '../common/cancellationUtils';
3024
import { LanguageClientMiddleware } from '../languageClientMiddleware';
3125
import { ProgressReporting } from '../progress';
3226
import { ILanguageClientFactory, ILanguageServerProxy } from '../types';
33-
import { StopWatch } from '../../common/utils/stopWatch';
34-
import { getMemoryUsage } from '../../common/process/memory';
35-
import { killPidTree } from '../../common/process/rawProcessApis';
27+
import { killPid } from '../../common/process/rawProcessApis';
3628

3729
@injectable()
3830
export class JediLanguageServerProxy implements ILanguageServerProxy {
@@ -46,18 +38,11 @@ export class JediLanguageServerProxy implements ILanguageServerProxy {
4638

4739
private lsVersion: string | undefined;
4840

49-
private pidUsageFailures = { timer: new StopWatch(), counter: 0 };
50-
51-
private pythonSettings: IPythonSettings | undefined;
52-
53-
private timer?: NodeJS.Timer | number;
54-
5541
constructor(
5642
@inject(ILanguageClientFactory) private readonly factory: ILanguageClientFactory,
5743
@inject(ITestingService) private readonly testManager: ITestingService,
5844
@inject(IExperimentsManager) private readonly experiments: IExperimentsManager,
5945
@inject(IInterpreterPathService) private readonly interpreterPathService: IInterpreterPathService,
60-
@inject(IConfigurationService) private readonly configurationService: IConfigurationService,
6146
) {}
6247

6348
private static versionTelemetryProps(instance: JediLanguageServerProxy) {
@@ -73,7 +58,7 @@ export class JediLanguageServerProxy implements ILanguageServerProxy {
7358
const pid: number | undefined = ((this.languageClient as any)._serverProcess as ChildProcess)?.pid;
7459
const killServer = () => {
7560
if (pid) {
76-
killPidTree(pid);
61+
killPid(pid);
7762
}
7863
};
7964
// Do not await on this.
@@ -92,11 +77,6 @@ export class JediLanguageServerProxy implements ILanguageServerProxy {
9277
this.cancellationStrategy = undefined;
9378
}
9479

95-
if (this.timer) {
96-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
97-
clearTimeout(this.timer as any);
98-
}
99-
10080
while (this.disposables.length > 0) {
10181
const d = this.disposables.shift()!;
10282
d.dispose();
@@ -122,8 +102,6 @@ export class JediLanguageServerProxy implements ILanguageServerProxy {
122102
return this.serverReady();
123103
}
124104

125-
this.pythonSettings = this.configurationService.getSettings(resource);
126-
127105
this.lsVersion =
128106
(options.middleware ? (<LanguageClientMiddleware>options.middleware).serverVersion : undefined) ?? '0.19.3';
129107

@@ -150,13 +128,6 @@ export class JediLanguageServerProxy implements ILanguageServerProxy {
150128
}
151129

152130
await this.registerTestServices();
153-
154-
try {
155-
await this.checkJediLSPMemoryFootprint();
156-
} catch (ex) {
157-
// Ignore errors
158-
}
159-
160131
return Promise.resolve();
161132
}
162133

@@ -209,56 +180,4 @@ export class JediLanguageServerProxy implements ILanguageServerProxy {
209180
);
210181
}
211182
}
212-
213-
private async checkJediLSPMemoryFootprint() {
214-
// Check memory footprint periodically. Do not check on every request due to
215-
// the performance impact. See https://github.com/soyuka/pidusage - on Windows
216-
// it is using wmic which means spawning cmd.exe process on every request.
217-
if (this.pythonSettings && this.pythonSettings.jediMemoryLimit === -1) {
218-
return;
219-
}
220-
221-
await this.sendJediMemoryTelemetry();
222-
if (this.timer) {
223-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
224-
clearTimeout(this.timer as any);
225-
}
226-
this.timer = setTimeout(() => this.checkJediLSPMemoryFootprint(), 15 * 1000);
227-
}
228-
229-
private async sendJediMemoryTelemetry(): Promise<void> {
230-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
231-
const proc: ChildProcess | undefined = (this.languageClient as any)._serverProcess as ChildProcess;
232-
if (
233-
!proc ||
234-
proc.killed ||
235-
this.pidUsageFailures.counter > 2 ||
236-
!this.pythonSettings ||
237-
this.pythonSettings.jediMemoryLimit === -1
238-
) {
239-
return;
240-
}
241-
242-
try {
243-
const memory = await getMemoryUsage(proc.pid);
244-
const limit = Math.min(Math.max(this.pythonSettings.jediMemoryLimit, 3072), 8192) * 1024 * 1024;
245-
if (memory > 0) {
246-
const props = {
247-
memUse: memory,
248-
limit,
249-
isUserDefinedLimit: limit !== 1024,
250-
restart: false,
251-
};
252-
sendTelemetryEvent(EventName.JEDI_MEMORY, undefined, props);
253-
}
254-
} catch (err) {
255-
this.pidUsageFailures.counter += 1;
256-
// If this function fails 2 times in the last 60 seconds, lets not try ever again.
257-
if (this.pidUsageFailures.timer.elapsedTime > 60 * 1000) {
258-
this.pidUsageFailures.counter = 0;
259-
this.pidUsageFailures.timer.reset();
260-
}
261-
traceError('Python Extension: (pidusage-tree)', err);
262-
}
263-
}
264183
}

src/client/common/process/memory.ts

-21
This file was deleted.

src/client/common/process/rawProcessApis.ts

-18
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ import {
1919
} from './types';
2020
import { noop } from '../utils/misc';
2121

22-
const pidUsageTree = require('pidusage-tree');
23-
2422
function getDefaultOptions<T extends ShellOptions | SpawnOptions>(options: T, defaultEnv?: EnvironmentVariables): T {
2523
const defaultOptions = { ...options };
2624
const execOptions = defaultOptions as SpawnOptions;
@@ -253,19 +251,3 @@ export function killPid(pid: number): void {
253251
// Ignore.
254252
}
255253
}
256-
257-
/**
258-
* Kills all processes spawned by `pid` (`pid` inclusive)
259-
* @param pid
260-
*/
261-
export async function killPidTree(pid: number): Promise<void> {
262-
try {
263-
// This can fail if the process is already killed
264-
const result = await pidUsageTree(pid);
265-
for (const key of Object.keys(result)) {
266-
killPid(parseInt(key, 10));
267-
}
268-
} catch (ex) {
269-
// Ignore.
270-
}
271-
}

0 commit comments

Comments
 (0)