Skip to content

Commit 7dadd34

Browse files
Clean up WaitForSessionFile logic and support increasing timeout with warning (#2653)
* Add better sessionfile wait logic with setting * clean up logic * move into process.ts to use vscode api * use timeout seconds Co-authored-by: Tyler Leonhardt (POWERSHELL) <tyleonha@microsoft.com>
1 parent 79d7313 commit 7dadd34

File tree

5 files changed

+39
-32
lines changed

5 files changed

+39
-32
lines changed

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,11 @@
761761
"default": null,
762762
"description": "An array of strings that enable experimental features in the PowerShell extension."
763763
},
764+
"powershell.developer.waitForSessionFileTimeoutSeconds": {
765+
"type": "number",
766+
"default": 240,
767+
"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)"
768+
},
764769
"powershell.pester.useLegacyCodeLens": {
765770
"type": "boolean",
766771
"default": true,

src/process.ts

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ export class PowerShellProcess {
1717
return pspath.replace(new RegExp("'", "g"), "''");
1818
}
1919

20+
// This is used to warn the user that the extension is taking longer than expected to startup.
21+
// After the 15th try we've hit 30 seconds and should warn.
22+
private static warnUserThreshold = 15;
23+
2024
public onExited: vscode.Event<void>;
2125
private onExitedEmitter = new vscode.EventEmitter<void>();
2226

@@ -174,20 +178,36 @@ export class PowerShellProcess {
174178
return true;
175179
}
176180

177-
private waitForSessionFile(): Promise<utils.IEditorServicesSessionDetails> {
178-
return new Promise((resolve, reject) => {
179-
utils.waitForSessionFile(this.sessionFilePath, (sessionDetails, error) => {
180-
utils.deleteSessionFile(this.sessionFilePath);
181+
private sleep(ms: number) {
182+
return new Promise(resolve => setTimeout(resolve, ms));
183+
}
181184

182-
if (error) {
183-
this.log.write(`Error occurred retrieving session file:\n${error}`);
184-
return reject(error);
185-
}
185+
private async waitForSessionFile(): Promise<utils.IEditorServicesSessionDetails> {
186+
// Determine how many tries by dividing by 2000 thus checking every 2 seconds.
187+
const numOfTries = this.sessionSettings.developer.waitForSessionFileTimeoutSeconds / 2;
188+
const warnAt = numOfTries - PowerShellProcess.warnUserThreshold;
186189

190+
// Check every 2 seconds
191+
for (let i = numOfTries; i > 0; i--) {
192+
if (utils.checkIfFileExists(this.sessionFilePath)) {
187193
this.log.write("Session file found");
188-
resolve(sessionDetails);
189-
});
190-
});
194+
const sessionDetails = utils.readSessionFile(this.sessionFilePath);
195+
utils.deleteSessionFile(this.sessionFilePath);
196+
return sessionDetails;
197+
}
198+
199+
if (warnAt === i) {
200+
vscode.window.showWarningMessage(`Loading the PowerShell extension is taking longer than expected.
201+
If you're using privilege enforcement software, this can affect start up performance.`);
202+
}
203+
204+
// Wait a bit and try again
205+
await this.sleep(2000);
206+
}
207+
208+
const err = "Timed out waiting for session file to appear.";
209+
this.log.write(err);
210+
throw new Error(err);
191211
}
192212

193213
private onTerminalClose(terminal: vscode.Terminal) {

src/settings.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export interface IDeveloperSettings {
7272
bundledModulesPath?: string;
7373
editorServicesLogLevel?: string;
7474
editorServicesWaitForDebugger?: boolean;
75+
waitForSessionFileTimeoutSeconds?: number;
7576
}
7677

7778
export interface ISettings {
@@ -142,6 +143,7 @@ export function load(): ISettings {
142143
bundledModulesPath: "../../../PowerShellEditorServices/module",
143144
editorServicesLogLevel: "Normal",
144145
editorServicesWaitForDebugger: false,
146+
waitForSessionFileTimeoutSeconds: 240,
145147
};
146148

147149
const defaultCodeFoldingSettings: ICodeFoldingSettings = {

src/utils.ts

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ export interface IEditorServicesSessionDetails {
4545
}
4646

4747
export type IReadSessionFileCallback = (details: IEditorServicesSessionDetails) => void;
48-
export type IWaitForSessionFileCallback = (details: IEditorServicesSessionDetails, error: string) => void;
4948

5049
const sessionsFolder = path.resolve(__dirname, "..", "..", "sessions/");
5150
const sessionFilePathPrefix = path.resolve(sessionsFolder, "PSES-VSCode-" + process.env.VSCODE_PID);
@@ -69,25 +68,6 @@ export function writeSessionFile(sessionFilePath: string, sessionDetails: IEdito
6968
writeStream.close();
7069
}
7170

72-
export function waitForSessionFile(sessionFilePath: string, callback: IWaitForSessionFileCallback) {
73-
74-
function innerTryFunc(remainingTries: number, delayMilliseconds: number) {
75-
if (remainingTries === 0) {
76-
callback(undefined, "Timed out waiting for session file to appear.");
77-
} else if (!checkIfFileExists(sessionFilePath)) {
78-
// Wait a bit and try again
79-
setTimeout(
80-
() => { innerTryFunc(remainingTries - 1, delayMilliseconds); },
81-
delayMilliseconds);
82-
} else {
83-
// Session file was found, load and return it
84-
callback(readSessionFile(sessionFilePath), undefined);
85-
}
86-
}
87-
88-
// Try once every 2 seconds, 60 times - making two full minutes
89-
innerTryFunc(60, 2000);
90-
}
9171

9272
export function readSessionFile(sessionFilePath: string): IEditorServicesSessionDetails {
9373
const fileContents = fs.readFileSync(sessionFilePath, "utf-8");

0 commit comments

Comments
 (0)