From 4616ec0255f2c29658d565a85fdd5e38f7588b92 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 22 Mar 2018 15:26:24 -0700 Subject: [PATCH 1/2] :bug: ability to turn off check and add threshold check --- package.json | 4 +- src/client/{telemetry => common}/stopWatch.ts | 3 + src/client/debugger/Common/telemetry.ts | 2 +- src/client/extension.ts | 2 +- src/client/formatters/autoPep8Formatter.ts | 2 +- src/client/formatters/yapfFormatter.ts | 2 +- .../configuration/pythonPathUpdaterService.ts | 2 +- src/client/linters/lintingEngine.ts | 304 +++++++++--------- src/client/providers/jediProxy.ts | 33 +- .../providers/simpleRefactorProvider.ts | 2 +- src/client/telemetry/index.ts | 2 +- src/client/telemetry/types.ts | 6 +- 12 files changed, 194 insertions(+), 170 deletions(-) rename src/client/{telemetry => common}/stopWatch.ts (80%) diff --git a/package.json b/package.json index 0b0b476f7372..1f02e3e4b730 100644 --- a/package.json +++ b/package.json @@ -1007,8 +1007,8 @@ }, "python.jediMemoryLimit": { "type": "number", - "default": "0", - "description": "Memory limit for the Jedi completion engine in megabytes. Zero (default) means 1024 MB", + "default": 0, + "description": "Memory limit for the Jedi completion engine in megabytes. Zero (default) means 1024 MB. -1 means unlimited (disable memory limit check)", "scope": "resource" }, "python.sortImports.path": { diff --git a/src/client/telemetry/stopWatch.ts b/src/client/common/stopWatch.ts similarity index 80% rename from src/client/telemetry/stopWatch.ts rename to src/client/common/stopWatch.ts index 3e2a2132e94d..a72b3f3ae349 100644 --- a/src/client/telemetry/stopWatch.ts +++ b/src/client/common/stopWatch.ts @@ -8,4 +8,7 @@ export class StopWatch { public get elapsedTime() { return Date.now() - this.started; } + public reset(){ + this.started = Date.now(); + } } diff --git a/src/client/debugger/Common/telemetry.ts b/src/client/debugger/Common/telemetry.ts index 2e454c350379..9cb9fd3dc24a 100644 --- a/src/client/debugger/Common/telemetry.ts +++ b/src/client/debugger/Common/telemetry.ts @@ -4,8 +4,8 @@ // tslint:disable:no-function-expression no-any no-invalid-this no-use-before-declare import { DebugSession, StoppedEvent } from 'vscode-debugadapter'; +import { StopWatch } from '../../common/stopWatch'; import { DEBUGGER_PERFORMANCE } from '../../telemetry/constants'; -import { StopWatch } from '../../telemetry/stopWatch'; import { DebuggerPerformanceTelemetry } from '../../telemetry/types'; import { TelemetryEvent } from './Contracts'; diff --git a/src/client/extension.ts b/src/client/extension.ts index 1a2eb6b7cb19..e680bfb21553 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -20,6 +20,7 @@ import { registerTypes as installerRegisterTypes } from './common/installer/serv import { registerTypes as platformRegisterTypes } from './common/platform/serviceRegistry'; import { registerTypes as processRegisterTypes } from './common/process/serviceRegistry'; import { registerTypes as commonRegisterTypes } from './common/serviceRegistry'; +import { StopWatch } from './common/stopWatch'; import { GLOBAL_MEMENTO, IDisposableRegistry, ILogger, IMemento, IOutputChannel, IPersistentStateFactory, WORKSPACE_MEMENTO } from './common/types'; import { registerTypes as variableRegisterTypes } from './common/variables/serviceRegistry'; import { BaseConfigurationProvider } from './debugger/configProviders/baseProvider'; @@ -53,7 +54,6 @@ import { activateUpdateSparkLibraryProvider } from './providers/updateSparkLibra import * as sortImports from './sortImports'; import { sendTelemetryEvent } from './telemetry'; import { EDITOR_LOAD } from './telemetry/constants'; -import { StopWatch } from './telemetry/stopWatch'; import { registerTypes as commonRegisterTerminalTypes } from './terminals/serviceRegistry'; import { ICodeExecutionManager } from './terminals/types'; import { BlockFormatProviders } from './typeFormatters/blockFormatProvider'; diff --git a/src/client/formatters/autoPep8Formatter.ts b/src/client/formatters/autoPep8Formatter.ts index 316fab349cc9..b3818c8eef0e 100644 --- a/src/client/formatters/autoPep8Formatter.ts +++ b/src/client/formatters/autoPep8Formatter.ts @@ -1,10 +1,10 @@ import * as vscode from 'vscode'; import { Product } from '../common/installer/productInstaller'; +import { StopWatch } from '../common/stopWatch'; import { IConfigurationService } from '../common/types'; import { IServiceContainer } from '../ioc/types'; import { sendTelemetryWhenDone } from '../telemetry'; import { FORMAT } from '../telemetry/constants'; -import { StopWatch } from '../telemetry/stopWatch'; import { BaseFormatter } from './baseFormatter'; export class AutoPep8Formatter extends BaseFormatter { diff --git a/src/client/formatters/yapfFormatter.ts b/src/client/formatters/yapfFormatter.ts index 31a768ca0a57..7482970c35d0 100644 --- a/src/client/formatters/yapfFormatter.ts +++ b/src/client/formatters/yapfFormatter.ts @@ -1,9 +1,9 @@ import * as vscode from 'vscode'; +import { StopWatch } from '../common/stopWatch'; import { IConfigurationService, Product } from '../common/types'; import { IServiceContainer } from '../ioc/types'; import { sendTelemetryWhenDone } from '../telemetry'; import { FORMAT } from '../telemetry/constants'; -import { StopWatch } from '../telemetry/stopWatch'; import { BaseFormatter } from './baseFormatter'; export class YapfFormatter extends BaseFormatter { diff --git a/src/client/interpreter/configuration/pythonPathUpdaterService.ts b/src/client/interpreter/configuration/pythonPathUpdaterService.ts index 67a6e0f5009d..812fcd48b6de 100644 --- a/src/client/interpreter/configuration/pythonPathUpdaterService.ts +++ b/src/client/interpreter/configuration/pythonPathUpdaterService.ts @@ -1,10 +1,10 @@ import { inject, injectable } from 'inversify'; import * as path from 'path'; import { ConfigurationTarget, Uri, window } from 'vscode'; +import { StopWatch } from '../../common/stopWatch'; import { IServiceContainer } from '../../ioc/types'; import { sendTelemetryEvent } from '../../telemetry'; import { PYTHON_INTERPRETER } from '../../telemetry/constants'; -import { StopWatch } from '../../telemetry/stopWatch'; import { PythonInterpreterTelemetry } from '../../telemetry/types'; import { IInterpreterVersionService } from '../contracts'; import { IPythonPathUpdaterServiceFactory, IPythonPathUpdaterServiceManager } from './types'; diff --git a/src/client/linters/lintingEngine.ts b/src/client/linters/lintingEngine.ts index 650df50fa913..d5323c697c43 100644 --- a/src/client/linters/lintingEngine.ts +++ b/src/client/linters/lintingEngine.ts @@ -8,12 +8,12 @@ import * as vscode from 'vscode'; import { IDocumentManager, IWorkspaceService } from '../common/application/types'; import { LinterErrors, STANDARD_OUTPUT_CHANNEL } from '../common/constants'; import { IFileSystem } from '../common/platform/types'; +import { StopWatch } from '../common/stopWatch'; import { IConfigurationService, IOutputChannel } from '../common/types'; import { IServiceContainer } from '../ioc/types'; import { JupyterProvider } from '../jupyter/provider'; import { sendTelemetryWhenDone } from '../telemetry'; import { LINTING } from '../telemetry/constants'; -import { StopWatch } from '../telemetry/stopWatch'; import { LinterTrigger, LintingTelemetry } from '../telemetry/types'; import { ILinterInfo, ILinterManager, ILintingEngine, ILintMessage, LintMessageSeverity } from './types'; @@ -27,176 +27,176 @@ lintSeverityToVSSeverity.set(LintMessageSeverity.Warning, vscode.DiagnosticSever // tslint:disable-next-line:interface-name interface DocumentHasJupyterCodeCells { - // tslint:disable-next-line:callable-types - (doc: vscode.TextDocument, token: vscode.CancellationToken): Promise; + // tslint:disable-next-line:callable-types + (doc: vscode.TextDocument, token: vscode.CancellationToken): Promise; } @injectable() export class LintingEngine implements ILintingEngine { - private documentHasJupyterCodeCells: DocumentHasJupyterCodeCells; - private workspace: IWorkspaceService; - private documents: IDocumentManager; - private configurationService: IConfigurationService; - private linterManager: ILinterManager; - private diagnosticCollection: vscode.DiagnosticCollection; - private pendingLintings = new Map(); - private outputChannel: vscode.OutputChannel; - private fileSystem: IFileSystem; - - constructor(@inject(IServiceContainer) private serviceContainer: IServiceContainer) { - this.documentHasJupyterCodeCells = (a, b) => Promise.resolve(false); - this.documents = serviceContainer.get(IDocumentManager); - this.workspace = serviceContainer.get(IWorkspaceService); - this.configurationService = serviceContainer.get(IConfigurationService); - this.outputChannel = serviceContainer.get(IOutputChannel, STANDARD_OUTPUT_CHANNEL); - this.linterManager = serviceContainer.get(ILinterManager); - this.fileSystem = serviceContainer.get(IFileSystem); - this.diagnosticCollection = vscode.languages.createDiagnosticCollection('python'); - } - - public get diagnostics(): vscode.DiagnosticCollection { - return this.diagnosticCollection; - } - - public clearDiagnostics(document: vscode.TextDocument): void { - if (this.diagnosticCollection.has(document.uri)) { - this.diagnosticCollection.delete(document.uri); + private documentHasJupyterCodeCells: DocumentHasJupyterCodeCells; + private workspace: IWorkspaceService; + private documents: IDocumentManager; + private configurationService: IConfigurationService; + private linterManager: ILinterManager; + private diagnosticCollection: vscode.DiagnosticCollection; + private pendingLintings = new Map(); + private outputChannel: vscode.OutputChannel; + private fileSystem: IFileSystem; + + constructor(@inject(IServiceContainer) private serviceContainer: IServiceContainer) { + this.documentHasJupyterCodeCells = (a, b) => Promise.resolve(false); + this.documents = serviceContainer.get(IDocumentManager); + this.workspace = serviceContainer.get(IWorkspaceService); + this.configurationService = serviceContainer.get(IConfigurationService); + this.outputChannel = serviceContainer.get(IOutputChannel, STANDARD_OUTPUT_CHANNEL); + this.linterManager = serviceContainer.get(ILinterManager); + this.fileSystem = serviceContainer.get(IFileSystem); + this.diagnosticCollection = vscode.languages.createDiagnosticCollection('python'); } - } - public async lintOpenPythonFiles(): Promise { - this.diagnosticCollection.clear(); - const promises = this.documents.textDocuments.map(async document => await this.lintDocument(document, 'auto')); - await Promise.all(promises); - return this.diagnosticCollection; - } - - public async lintDocument(document: vscode.TextDocument, trigger: LinterTrigger): Promise { - this.diagnosticCollection.set(document.uri, []); + public get diagnostics(): vscode.DiagnosticCollection { + return this.diagnosticCollection; + } - // Check if we need to lint this document - if (!await this.shouldLintDocument(document)) { - return; + public clearDiagnostics(document: vscode.TextDocument): void { + if (this.diagnosticCollection.has(document.uri)) { + this.diagnosticCollection.delete(document.uri); + } } - if (this.pendingLintings.has(document.uri.fsPath)) { - this.pendingLintings.get(document.uri.fsPath)!.cancel(); - this.pendingLintings.delete(document.uri.fsPath); + public async lintOpenPythonFiles(): Promise { + this.diagnosticCollection.clear(); + const promises = this.documents.textDocuments.map(async document => await this.lintDocument(document, 'auto')); + await Promise.all(promises); + return this.diagnosticCollection; } - const cancelToken = new vscode.CancellationTokenSource(); - cancelToken.token.onCancellationRequested(() => { - if (this.pendingLintings.has(document.uri.fsPath)) { - this.pendingLintings.delete(document.uri.fsPath); - } - }); - - this.pendingLintings.set(document.uri.fsPath, cancelToken); - this.outputChannel.clear(); - - const promises: Promise[] = this.linterManager.getActiveLinters(document.uri) - .map(info => { - const stopWatch = new StopWatch(); - const linter = this.linterManager.createLinter(info.product, this.outputChannel, this.serviceContainer, document.uri); - const promise = linter.lint(document, cancelToken.token); - this.sendLinterRunTelemetry(info, document.uri, promise, stopWatch, trigger); - return promise; - }); - - const hasJupyterCodeCells = await this.documentHasJupyterCodeCells(document, cancelToken.token); - // linters will resolve asynchronously - keep a track of all - // diagnostics reported as them come in. - let diagnostics: vscode.Diagnostic[] = []; - const settings = this.configurationService.getSettings(document.uri); - - for (const p of promises) { - const msgs = await p; - if (cancelToken.token.isCancellationRequested) { - break; - } - - if (this.isDocumentOpen(document.uri)) { - // Build the message and suffix the message with the name of the linter used. - for (const m of msgs) { - // Ignore magic commands from jupyter. - if (hasJupyterCodeCells && document.lineAt(m.line - 1).text.trim().startsWith('%') && - (m.code === LinterErrors.pylint.InvalidSyntax || - m.code === LinterErrors.prospector.InvalidSyntax || - m.code === LinterErrors.flake8.InvalidSyntax)) { - continue; - } - diagnostics.push(this.createDiagnostics(m, document)); + public async lintDocument(document: vscode.TextDocument, trigger: LinterTrigger): Promise { + this.diagnosticCollection.set(document.uri, []); + + // Check if we need to lint this document + if (!await this.shouldLintDocument(document)) { + return; } - // Limit the number of messages to the max value. - diagnostics = diagnostics.filter((value, index) => index <= settings.linting.maxNumberOfProblems); - } - } - // Set all diagnostics found in this pass, as this method always clears existing diagnostics. - this.diagnosticCollection.set(document.uri, diagnostics); - } - - // tslint:disable-next-line:no-any - public async linkJupiterExtension(jupiter: vscode.Extension | undefined): Promise { - if (!jupiter) { - return; + + if (this.pendingLintings.has(document.uri.fsPath)) { + this.pendingLintings.get(document.uri.fsPath)!.cancel(); + this.pendingLintings.delete(document.uri.fsPath); + } + + const cancelToken = new vscode.CancellationTokenSource(); + cancelToken.token.onCancellationRequested(() => { + if (this.pendingLintings.has(document.uri.fsPath)) { + this.pendingLintings.delete(document.uri.fsPath); + } + }); + + this.pendingLintings.set(document.uri.fsPath, cancelToken); + this.outputChannel.clear(); + + const promises: Promise[] = this.linterManager.getActiveLinters(document.uri) + .map(info => { + const stopWatch = new StopWatch(); + const linter = this.linterManager.createLinter(info.product, this.outputChannel, this.serviceContainer, document.uri); + const promise = linter.lint(document, cancelToken.token); + this.sendLinterRunTelemetry(info, document.uri, promise, stopWatch, trigger); + return promise; + }); + + const hasJupyterCodeCells = await this.documentHasJupyterCodeCells(document, cancelToken.token); + // linters will resolve asynchronously - keep a track of all + // diagnostics reported as them come in. + let diagnostics: vscode.Diagnostic[] = []; + const settings = this.configurationService.getSettings(document.uri); + + for (const p of promises) { + const msgs = await p; + if (cancelToken.token.isCancellationRequested) { + break; + } + + if (this.isDocumentOpen(document.uri)) { + // Build the message and suffix the message with the name of the linter used. + for (const m of msgs) { + // Ignore magic commands from jupyter. + if (hasJupyterCodeCells && document.lineAt(m.line - 1).text.trim().startsWith('%') && + (m.code === LinterErrors.pylint.InvalidSyntax || + m.code === LinterErrors.prospector.InvalidSyntax || + m.code === LinterErrors.flake8.InvalidSyntax)) { + continue; + } + diagnostics.push(this.createDiagnostics(m, document)); + } + // Limit the number of messages to the max value. + diagnostics = diagnostics.filter((value, index) => index <= settings.linting.maxNumberOfProblems); + } + } + // Set all diagnostics found in this pass, as this method always clears existing diagnostics. + this.diagnosticCollection.set(document.uri, diagnostics); } - if (!jupiter.isActive) { - await jupiter.activate(); + + // tslint:disable-next-line:no-any + public async linkJupiterExtension(jupiter: vscode.Extension | undefined): Promise { + if (!jupiter) { + return; + } + if (!jupiter.isActive) { + await jupiter.activate(); + } + // tslint:disable-next-line:no-unsafe-any + jupiter.exports.registerLanguageProvider(PYTHON.language, new JupyterProvider()); + // tslint:disable-next-line:no-unsafe-any + this.documentHasJupyterCodeCells = jupiter.exports.hasCodeCells; } - // tslint:disable-next-line:no-unsafe-any - jupiter.exports.registerLanguageProvider(PYTHON.language, new JupyterProvider()); - // tslint:disable-next-line:no-unsafe-any - this.documentHasJupyterCodeCells = jupiter.exports.hasCodeCells; - } - - private sendLinterRunTelemetry(info: ILinterInfo, resource: vscode.Uri, promise: Promise, stopWatch: StopWatch, trigger: LinterTrigger): void { - const linterExecutablePathName = info.pathName(resource); - const properties: LintingTelemetry = { - tool: info.id, - hasCustomArgs: info.linterArgs(resource).length > 0, - trigger, - executableSpecified: linterExecutablePathName.length > 0 - }; - sendTelemetryWhenDone(LINTING, promise, stopWatch, properties); - } - - private isDocumentOpen(uri: vscode.Uri): boolean { - return this.documents.textDocuments.some(document => document.uri.fsPath === uri.fsPath); - } - - private createDiagnostics(message: ILintMessage, document: vscode.TextDocument): vscode.Diagnostic { - const position = new vscode.Position(message.line - 1, message.column); - const range = new vscode.Range(position, position); - - const severity = lintSeverityToVSSeverity.get(message.severity!)!; - const diagnostic = new vscode.Diagnostic(range, `${message.code}:${message.message}`, severity); - diagnostic.code = message.code; - diagnostic.source = message.provider; - return diagnostic; - } - - private async shouldLintDocument(document: vscode.TextDocument): Promise { - if (!this.linterManager.isLintingEnabled(document.uri)) { - this.diagnosticCollection.set(document.uri, []); - return false; + + private sendLinterRunTelemetry(info: ILinterInfo, resource: vscode.Uri, promise: Promise, stopWatch: StopWatch, trigger: LinterTrigger): void { + const linterExecutablePathName = info.pathName(resource); + const properties: LintingTelemetry = { + tool: info.id, + hasCustomArgs: info.linterArgs(resource).length > 0, + trigger, + executableSpecified: linterExecutablePathName.length > 0 + }; + sendTelemetryWhenDone(LINTING, promise, stopWatch, properties); } - if (document.languageId !== PYTHON.language) { - return false; + private isDocumentOpen(uri: vscode.Uri): boolean { + return this.documents.textDocuments.some(document => document.uri.fsPath === uri.fsPath); } - const workspaceFolder = this.workspace.getWorkspaceFolder(document.uri); - const workspaceRootPath = (workspaceFolder && typeof workspaceFolder.uri.fsPath === 'string') ? workspaceFolder.uri.fsPath : undefined; - const relativeFileName = typeof workspaceRootPath === 'string' ? path.relative(workspaceRootPath, document.fileName) : document.fileName; + private createDiagnostics(message: ILintMessage, document: vscode.TextDocument): vscode.Diagnostic { + const position = new vscode.Position(message.line - 1, message.column); + const range = new vscode.Range(position, position); - const settings = this.configurationService.getSettings(document.uri); - const ignoreMinmatches = settings.linting.ignorePatterns.map(pattern => new Minimatch(pattern)); - if (ignoreMinmatches.some(matcher => matcher.match(document.fileName) || matcher.match(relativeFileName))) { - return false; + const severity = lintSeverityToVSSeverity.get(message.severity!)!; + const diagnostic = new vscode.Diagnostic(range, `${message.code}:${message.message}`, severity); + diagnostic.code = message.code; + diagnostic.source = message.provider; + return diagnostic; } - if (document.uri.scheme !== 'file' || !document.uri.fsPath) { - return false; + + private async shouldLintDocument(document: vscode.TextDocument): Promise { + if (!this.linterManager.isLintingEnabled(document.uri)) { + this.diagnosticCollection.set(document.uri, []); + return false; + } + + if (document.languageId !== PYTHON.language) { + return false; + } + + const workspaceFolder = this.workspace.getWorkspaceFolder(document.uri); + const workspaceRootPath = (workspaceFolder && typeof workspaceFolder.uri.fsPath === 'string') ? workspaceFolder.uri.fsPath : undefined; + const relativeFileName = typeof workspaceRootPath === 'string' ? path.relative(workspaceRootPath, document.fileName) : document.fileName; + + const settings = this.configurationService.getSettings(document.uri); + const ignoreMinmatches = settings.linting.ignorePatterns.map(pattern => new Minimatch(pattern)); + if (ignoreMinmatches.some(matcher => matcher.match(document.fileName) || matcher.match(relativeFileName))) { + return false; + } + if (document.uri.scheme !== 'file' || !document.uri.fsPath) { + return false; + } + return await this.fileSystem.fileExistsAsync(document.uri.fsPath); } - return await this.fileSystem.fileExistsAsync(document.uri.fsPath); - } } diff --git a/src/client/providers/jediProxy.ts b/src/client/providers/jediProxy.ts index fcf9b7c7e523..f0136585786f 100644 --- a/src/client/providers/jediProxy.ts +++ b/src/client/providers/jediProxy.ts @@ -14,6 +14,7 @@ import { debounce, swallowExceptions } from '../common/decorators'; import '../common/extensions'; import { createDeferred, Deferred } from '../common/helpers'; import { IPythonExecutionFactory } from '../common/process/types'; +import { StopWatch } from '../common/stopWatch'; import { ILogger } from '../common/types'; import { IEnvironmentVariablesProvider } from '../common/variables/types'; import { IServiceContainer } from '../ioc/types'; @@ -131,7 +132,7 @@ commandNames.set(CommandType.Usages, 'usages'); commandNames.set(CommandType.Symbols, 'names'); export class JediProxy implements vscode.Disposable { - private proc: ChildProcess | null; + private proc?: ChildProcess; private pythonSettings: PythonSettings; private cmdId: number = 0; private lastKnownPythonInterpreter: string; @@ -141,10 +142,12 @@ export class JediProxy implements vscode.Disposable { private spawnRetryAttempts = 0; private additionalAutoCompletePaths: string[] = []; private workspacePath: string; - private languageServerStarted: Deferred; + private languageServerStarted!: Deferred; private initialized: Deferred; - private environmentVariablesProvider: IEnvironmentVariablesProvider; + private environmentVariablesProvider!: IEnvironmentVariablesProvider; private logger: ILogger; + private ignoreJediMemoryFootprint: boolean = false; + private pidUsageFailures = { timer: new StopWatch(), counter: 0 }; public constructor(private extensionRootDir: string, workspacePath: string, private serviceContainer: IServiceContainer) { this.workspacePath = workspacePath; @@ -158,7 +161,9 @@ export class JediProxy implements vscode.Disposable { // Check memory footprint periodically. Do not check on every request due to // the performance impact. See https://github.com/soyuka/pidusage - on Windows // it is using wmic which means spawning cmd.exe process on every request. - setInterval(() => this.checkJediMemoryFootprint(), 2000); + if (this.shouldCheckJediMemoryFootprint()) { + setInterval(() => this.checkJediMemoryFootprint(), 2000); + } } private static getProperty(o: object, name: string): T { @@ -212,13 +217,28 @@ export class JediProxy implements vscode.Disposable { this.handleError('spawnProcess', ex); }); } - + private shouldCheckJediMemoryFootprint() { + if (this.ignoreJediMemoryFootprint || this.pythonSettings.jediMemoryLimit === -1) { + return false; + } + return true; + } private checkJediMemoryFootprint() { if (!this.proc || this.proc.killed) { return; } + if (!this.shouldCheckJediMemoryFootprint()) { + return; + } pidusage.stat(this.proc.pid, async (err, result) => { if (err) { + this.pidUsageFailures.counter += 1; + // If this function fails 5 times in the last 30 seconds, lets not try ever again. + if (this.pidUsageFailures.timer.elapsedTime > 30 * 1000) { + this.ignoreJediMemoryFootprint = this.pidUsageFailures.counter > 5; + this.pidUsageFailures.counter = 0; + this.pidUsageFailures.timer.reset(); + } return console.error('Python Extension: (pidusage)', err); } const limit = Math.min(Math.max(this.pythonSettings.jediMemoryLimit, 1024), 8192); @@ -276,7 +296,7 @@ export class JediProxy implements vscode.Disposable { } // tslint:disable-next-line:no-empty } catch (ex) { } - this.proc = null; + this.proc = undefined; } private handleError(source: string, errorMessage: string) { @@ -512,6 +532,7 @@ export class JediProxy implements vscode.Disposable { private onArguments(command: IExecutionCommand, response: object): void { // tslint:disable-next-line:no-any const defs = JediProxy.getProperty(response, 'results'); + // tslint:disable-next-line:no-object-literal-type-assertion this.safeResolve(command, { requestId: command.id, definitions: defs diff --git a/src/client/providers/simpleRefactorProvider.ts b/src/client/providers/simpleRefactorProvider.ts index f6b1772dc19f..513ae8ff9c85 100644 --- a/src/client/providers/simpleRefactorProvider.ts +++ b/src/client/providers/simpleRefactorProvider.ts @@ -1,12 +1,12 @@ import * as vscode from 'vscode'; import { PythonSettings } from '../common/configSettings'; import { getTextEditsFromPatch } from '../common/editor'; +import { StopWatch } from '../common/stopWatch'; import { IInstaller, Product } from '../common/types'; import { IServiceContainer } from '../ioc/types'; import { RefactorProxy } from '../refactor/proxy'; import { sendTelemetryWhenDone } from '../telemetry'; import { REFACTOR_EXTRACT_FUNCTION, REFACTOR_EXTRACT_VAR } from '../telemetry/constants'; -import { StopWatch } from '../telemetry/stopWatch'; type RenameResponse = { results: [{ diff: string }]; diff --git a/src/client/telemetry/index.ts b/src/client/telemetry/index.ts index 559e7b61d99a..adf0952fa7d5 100644 --- a/src/client/telemetry/index.ts +++ b/src/client/telemetry/index.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { StopWatch } from './stopWatch'; +import { StopWatch } from '../common/stopWatch'; import { getTelemetryReporter } from './telemetry'; import { TelemetryProperties } from './types'; diff --git a/src/client/telemetry/types.ts b/src/client/telemetry/types.ts index ed1cedaa1777..f8964590a324 100644 --- a/src/client/telemetry/types.ts +++ b/src/client/telemetry/types.ts @@ -30,7 +30,7 @@ export type CodeExecutionTelemetry = { scope: 'file' | 'selection'; }; export type DebuggerTelemetry = { - trigger: 'launch' | 'attach' + trigger: 'launch' | 'attach'; console?: 'none' | 'integratedTerminal' | 'externalTerminal'; debugOptions?: string; pyspark?: boolean; @@ -41,14 +41,14 @@ export type DebuggerPerformanceTelemetry = { action: 'stepIn' | 'stepOut' | 'continue' | 'next' | 'launch'; }; export type TestRunTelemetry = { - tool: 'nosetest' | 'pytest' | 'unittest' + tool: 'nosetest' | 'pytest' | 'unittest'; scope: 'currentFile' | 'all' | 'file' | 'class' | 'function' | 'failed'; debugging: boolean; trigger: 'ui' | 'codelens' | 'commandpalette' | 'auto'; failed: boolean; }; export type TestDiscoverytTelemetry = { - tool: 'nosetest' | 'pytest' | 'unittest' + tool: 'nosetest' | 'pytest' | 'unittest'; trigger: 'ui' | 'commandpalette'; failed: boolean; }; From 4d04d6d566d33db935bbbae2f4cf335626fe44f5 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 22 Mar 2018 15:26:34 -0700 Subject: [PATCH 2/2] :memo: news entry --- news/2 Fixes/1036.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 news/2 Fixes/1036.md diff --git a/news/2 Fixes/1036.md b/news/2 Fixes/1036.md new file mode 100644 index 000000000000..3992f412b521 --- /dev/null +++ b/news/2 Fixes/1036.md @@ -0,0 +1,5 @@ +Add ability to disable the check on memory usage of language server (Jedi) process. +To turn off this check, add the following setting into your user or workspace settings (`settings.json`) file: +```json +"python.jediMemoryLimit": -1 +```