From b6513e5a3a56f824a4cad3d66923b57f771b18e1 Mon Sep 17 00:00:00 2001 From: "Tyler Leonhardt (POWERSHELL)" Date: Tue, 21 Apr 2020 17:19:30 -0700 Subject: [PATCH 1/4] Add better sessionfile wait logic with setting --- package.json | 5 +++++ src/process.ts | 2 +- src/settings.ts | 2 ++ src/utils.ts | 12 ++++++++++-- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index f428a91059..b706a49095 100644 --- a/package.json +++ b/package.json @@ -761,6 +761,11 @@ "default": null, "description": "An array of strings that enable experimental features in the PowerShell extension." }, + "powershell.developer.waitForSessionFileNumOfTries": { + "type":"number", + "default": 120, + "description": "When the PowerShell extension is starting up, it checks for a session file in order to connect to the language server. It checks this number of times ever 2 seconds." + }, "powershell.pester.useLegacyCodeLens": { "type": "boolean", "default": true, diff --git a/src/process.ts b/src/process.ts index d77fe8b8b8..2f33df3345 100644 --- a/src/process.ts +++ b/src/process.ts @@ -176,7 +176,7 @@ export class PowerShellProcess { private waitForSessionFile(): Promise { return new Promise((resolve, reject) => { - utils.waitForSessionFile(this.sessionFilePath, (sessionDetails, error) => { + utils.waitForSessionFile(this.sessionFilePath, this.sessionSettings.developer.waitForSessionFileNumOfTries, (sessionDetails, error) => { utils.deleteSessionFile(this.sessionFilePath); if (error) { diff --git a/src/settings.ts b/src/settings.ts index 9c81b2cc27..aba67c48cb 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -72,6 +72,7 @@ export interface IDeveloperSettings { bundledModulesPath?: string; editorServicesLogLevel?: string; editorServicesWaitForDebugger?: boolean; + waitForSessionFileNumOfTries?: number; } export interface ISettings { @@ -142,6 +143,7 @@ export function load(): ISettings { bundledModulesPath: "../../../PowerShellEditorServices/module", editorServicesLogLevel: "Normal", editorServicesWaitForDebugger: false, + waitForSessionFileNumOfTries: 120, }; const defaultCodeFoldingSettings: ICodeFoldingSettings = { diff --git a/src/utils.ts b/src/utils.ts index 57527cf529..1924102d22 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -7,6 +7,7 @@ import fs = require("fs"); import os = require("os"); import path = require("path"); +import * as vscode from "vscode"; export const PowerShellLanguageId = "powershell"; @@ -69,12 +70,19 @@ export function writeSessionFile(sessionFilePath: string, sessionDetails: IEdito writeStream.close(); } -export function waitForSessionFile(sessionFilePath: string, callback: IWaitForSessionFileCallback) { +export function waitForSessionFile(sessionFilePath: string, numOfTries: number = 120, callback: IWaitForSessionFileCallback) { + // This is used to warn the user that the extension is taking longer than expected to startup. + const warnUserThreshold = numOfTries / 2; function innerTryFunc(remainingTries: number, delayMilliseconds: number) { if (remainingTries === 0) { callback(undefined, "Timed out waiting for session file to appear."); } else if (!checkIfFileExists(sessionFilePath)) { + if (warnUserThreshold === remainingTries) { + vscode.window.showWarningMessage(`Loading the PowerShell extension is taking longer than expected. +If you using anti-virus software, this can affect start up performance.`); + } + // Wait a bit and try again setTimeout( () => { innerTryFunc(remainingTries - 1, delayMilliseconds); }, @@ -86,7 +94,7 @@ export function waitForSessionFile(sessionFilePath: string, callback: IWaitForSe } // Try once every 2 seconds, 60 times - making two full minutes - innerTryFunc(60, 2000); + innerTryFunc(numOfTries, 2000); } export function readSessionFile(sessionFilePath: string): IEditorServicesSessionDetails { From 50b73769d0b369518714e062831f297e7623cea8 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Tue, 21 Apr 2020 18:08:33 -0700 Subject: [PATCH 2/4] clean up logic --- src/process.ts | 26 ++++++++++++-------------- src/utils.ts | 35 +++++++++++++++++------------------ 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/src/process.ts b/src/process.ts index 2f33df3345..d9a077f03f 100644 --- a/src/process.ts +++ b/src/process.ts @@ -174,20 +174,18 @@ export class PowerShellProcess { return true; } - private waitForSessionFile(): Promise { - return new Promise((resolve, reject) => { - utils.waitForSessionFile(this.sessionFilePath, this.sessionSettings.developer.waitForSessionFileNumOfTries, (sessionDetails, error) => { - utils.deleteSessionFile(this.sessionFilePath); - - if (error) { - this.log.write(`Error occurred retrieving session file:\n${error}`); - return reject(error); - } - - this.log.write("Session file found"); - resolve(sessionDetails); - }); - }); + private async waitForSessionFile(): Promise { + try { + const sessionDetails: utils.IEditorServicesSessionDetails = await utils.waitForSessionFile( + this.sessionFilePath, this.sessionSettings.developer.waitForSessionFileNumOfTries); + this.log.write("Session file found"); + return sessionDetails; + } catch (e) { + this.log.write(`Error occurred retrieving session file:\n${e}`); + throw e; + } finally { + utils.deleteSessionFile(this.sessionFilePath); + } } private onTerminalClose(terminal: vscode.Terminal) { diff --git a/src/utils.ts b/src/utils.ts index 1924102d22..d957637d8d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -70,31 +70,30 @@ export function writeSessionFile(sessionFilePath: string, sessionDetails: IEdito writeStream.close(); } -export function waitForSessionFile(sessionFilePath: string, numOfTries: number = 120, callback: IWaitForSessionFileCallback) { +function sleep(ms: number) { + return new Promise(resolve => setTimeout(resolve, ms)); +} +export async function waitForSessionFile(sessionFilePath: string, numOfTries: number = 120): Promise { // This is used to warn the user that the extension is taking longer than expected to startup. const warnUserThreshold = numOfTries / 2; - function innerTryFunc(remainingTries: number, delayMilliseconds: number) { - if (remainingTries === 0) { - callback(undefined, "Timed out waiting for session file to appear."); - } else if (!checkIfFileExists(sessionFilePath)) { - if (warnUserThreshold === remainingTries) { - vscode.window.showWarningMessage(`Loading the PowerShell extension is taking longer than expected. -If you using anti-virus software, this can affect start up performance.`); - } - - // Wait a bit and try again - setTimeout( - () => { innerTryFunc(remainingTries - 1, delayMilliseconds); }, - delayMilliseconds); - } else { + + for (let i = numOfTries; i > 0; i--) { + if (checkIfFileExists(sessionFilePath)) { // Session file was found, load and return it - callback(readSessionFile(sessionFilePath), undefined); + return readSessionFile(sessionFilePath); } + + if (warnUserThreshold === i) { + vscode.window.showWarningMessage(`Loading the PowerShell extension is taking longer than expected. +If you're using anti-virus software, this can affect start up performance.`); + } + + // Wait a bit and try again + await sleep(2000); } - // Try once every 2 seconds, 60 times - making two full minutes - innerTryFunc(numOfTries, 2000); + throw new Error("Timed out waiting for session file to appear."); } export function readSessionFile(sessionFilePath: string): IEditorServicesSessionDetails { From 79f97d38e1b772008d3213dedac9217211590879 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Tue, 21 Apr 2020 19:04:54 -0700 Subject: [PATCH 3/4] move into process.ts to use vscode api --- src/process.ts | 38 ++++++++++++++++++++++++++++---------- src/utils.ts | 26 -------------------------- 2 files changed, 28 insertions(+), 36 deletions(-) diff --git a/src/process.ts b/src/process.ts index d9a077f03f..2d87438124 100644 --- a/src/process.ts +++ b/src/process.ts @@ -174,18 +174,36 @@ export class PowerShellProcess { return true; } + private sleep(ms: number) { + return new Promise(resolve => setTimeout(resolve, ms)); + } + private async waitForSessionFile(): Promise { - try { - const sessionDetails: utils.IEditorServicesSessionDetails = await utils.waitForSessionFile( - this.sessionFilePath, this.sessionSettings.developer.waitForSessionFileNumOfTries); - this.log.write("Session file found"); - return sessionDetails; - } catch (e) { - this.log.write(`Error occurred retrieving session file:\n${e}`); - throw e; - } finally { - utils.deleteSessionFile(this.sessionFilePath); + const numOfTries = this.sessionSettings.developer.waitForSessionFileNumOfTries; + + // This is used to warn the user that the extension is taking longer than expected to startup. + const warnUserThreshold = numOfTries / 2; + + for (let i = numOfTries; i > 0; i--) { + if (utils.checkIfFileExists(this.sessionFilePath)) { + this.log.write("Session file found"); + const sessionDetails = utils.readSessionFile(this.sessionFilePath); + utils.deleteSessionFile(this.sessionFilePath); + return sessionDetails; + } + + if (warnUserThreshold === i) { + vscode.window.showWarningMessage(`Loading the PowerShell extension is taking longer than expected. + If you're using anti-virus software, this can affect start up performance.`); + } + + // Wait a bit and try again + await this.sleep(2000); } + + const err = "Timed out waiting for session file to appear."; + this.log.write(err); + throw new Error(err); } private onTerminalClose(terminal: vscode.Terminal) { diff --git a/src/utils.ts b/src/utils.ts index d957637d8d..bf22f7915d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -7,7 +7,6 @@ import fs = require("fs"); import os = require("os"); import path = require("path"); -import * as vscode from "vscode"; export const PowerShellLanguageId = "powershell"; @@ -70,31 +69,6 @@ export function writeSessionFile(sessionFilePath: string, sessionDetails: IEdito writeStream.close(); } -function sleep(ms: number) { - return new Promise(resolve => setTimeout(resolve, ms)); -} - -export async function waitForSessionFile(sessionFilePath: string, numOfTries: number = 120): Promise { - // This is used to warn the user that the extension is taking longer than expected to startup. - const warnUserThreshold = numOfTries / 2; - - for (let i = numOfTries; i > 0; i--) { - if (checkIfFileExists(sessionFilePath)) { - // Session file was found, load and return it - return readSessionFile(sessionFilePath); - } - - if (warnUserThreshold === i) { - vscode.window.showWarningMessage(`Loading the PowerShell extension is taking longer than expected. -If you're using anti-virus software, this can affect start up performance.`); - } - - // Wait a bit and try again - await sleep(2000); - } - - throw new Error("Timed out waiting for session file to appear."); -} export function readSessionFile(sessionFilePath: string): IEditorServicesSessionDetails { const fileContents = fs.readFileSync(sessionFilePath, "utf-8"); From ae1ee2cfc915a3c1a80353a083aee38193b1e1f4 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Wed, 22 Apr 2020 12:19:17 -0700 Subject: [PATCH 4/4] use timeout seconds --- package-lock.json | 2 +- package.json | 8 ++++---- src/process.ts | 16 ++++++++++------ src/settings.ts | 4 ++-- src/utils.ts | 1 - 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0b2e4ac05b..4d50a31ae2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "powershell-preview", - "version": "2020.4.2", + "version": "2020.4.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index b706a49095..7b707cde72 100644 --- a/package.json +++ b/package.json @@ -761,10 +761,10 @@ "default": null, "description": "An array of strings that enable experimental features in the PowerShell extension." }, - "powershell.developer.waitForSessionFileNumOfTries": { - "type":"number", - "default": 120, - "description": "When the PowerShell extension is starting up, it checks for a session file in order to connect to the language server. It checks this number of times ever 2 seconds." + "powershell.developer.waitForSessionFileTimeoutSeconds": { + "type": "number", + "default": 240, + "description": "When the PowerShell extension is starting up, it checks for a session file in order to connect to the language server. This setting determines how long until checking for the session file times out. (default is 240 seconds or 4 minutes)" }, "powershell.pester.useLegacyCodeLens": { "type": "boolean", diff --git a/src/process.ts b/src/process.ts index 2d87438124..80b849ef48 100644 --- a/src/process.ts +++ b/src/process.ts @@ -17,6 +17,10 @@ export class PowerShellProcess { return pspath.replace(new RegExp("'", "g"), "''"); } + // This is used to warn the user that the extension is taking longer than expected to startup. + // After the 15th try we've hit 30 seconds and should warn. + private static warnUserThreshold = 15; + public onExited: vscode.Event; private onExitedEmitter = new vscode.EventEmitter(); @@ -179,11 +183,11 @@ export class PowerShellProcess { } private async waitForSessionFile(): Promise { - const numOfTries = this.sessionSettings.developer.waitForSessionFileNumOfTries; - - // This is used to warn the user that the extension is taking longer than expected to startup. - const warnUserThreshold = numOfTries / 2; + // Determine how many tries by dividing by 2000 thus checking every 2 seconds. + const numOfTries = this.sessionSettings.developer.waitForSessionFileTimeoutSeconds / 2; + const warnAt = numOfTries - PowerShellProcess.warnUserThreshold; + // Check every 2 seconds for (let i = numOfTries; i > 0; i--) { if (utils.checkIfFileExists(this.sessionFilePath)) { this.log.write("Session file found"); @@ -192,9 +196,9 @@ export class PowerShellProcess { return sessionDetails; } - if (warnUserThreshold === i) { + if (warnAt === i) { vscode.window.showWarningMessage(`Loading the PowerShell extension is taking longer than expected. - If you're using anti-virus software, this can affect start up performance.`); + If you're using privilege enforcement software, this can affect start up performance.`); } // Wait a bit and try again diff --git a/src/settings.ts b/src/settings.ts index aba67c48cb..267134f84f 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -72,7 +72,7 @@ export interface IDeveloperSettings { bundledModulesPath?: string; editorServicesLogLevel?: string; editorServicesWaitForDebugger?: boolean; - waitForSessionFileNumOfTries?: number; + waitForSessionFileTimeoutSeconds?: number; } export interface ISettings { @@ -143,7 +143,7 @@ export function load(): ISettings { bundledModulesPath: "../../../PowerShellEditorServices/module", editorServicesLogLevel: "Normal", editorServicesWaitForDebugger: false, - waitForSessionFileNumOfTries: 120, + waitForSessionFileTimeoutSeconds: 240, }; const defaultCodeFoldingSettings: ICodeFoldingSettings = { diff --git a/src/utils.ts b/src/utils.ts index bf22f7915d..bf3c107a66 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -45,7 +45,6 @@ export interface IEditorServicesSessionDetails { } export type IReadSessionFileCallback = (details: IEditorServicesSessionDetails) => void; -export type IWaitForSessionFileCallback = (details: IEditorServicesSessionDetails, error: string) => void; const sessionsFolder = path.resolve(__dirname, "..", "..", "sessions/"); const sessionFilePathPrefix = path.resolve(sessionsFolder, "PSES-VSCode-" + process.env.VSCODE_PID);