@@ -26,7 +26,7 @@ import {
26
26
import { LanguageClientConsumer } from "./languageClientConsumer" ;
27
27
import { SemVer , satisfies } from "semver" ;
28
28
29
- export enum SessionStatus {
29
+ enum SessionStatus {
30
30
NotStarted = "Not Started" ,
31
31
Starting = "Starting" ,
32
32
Running = "Running" ,
@@ -146,11 +146,34 @@ export class SessionManager implements Middleware {
146
146
}
147
147
148
148
// The `exeNameOverride` is used by `restartSession` to override ANY other setting.
149
+ // We've made this function idempotent, so it can used to ensure the session has started.
149
150
public async start ( exeNameOverride ?: string ) : Promise < void > {
150
- // A simple lock because this function isn't re-entrant.
151
- if ( this . sessionStatus === SessionStatus . Starting ) {
151
+ switch ( this . sessionStatus ) {
152
+ case SessionStatus . NotStarted :
153
+ // Go ahead and start.
154
+ break ;
155
+ case SessionStatus . Starting :
156
+ // A simple lock because this function isn't re-entrant.
152
157
this . logger . writeWarning ( "Re-entered 'start' so waiting..." ) ;
153
- return await this . waitUntilStarted ( ) ;
158
+ return await this . waitWhileStarting ( ) ;
159
+ case SessionStatus . Running :
160
+ // We're started, just return.
161
+ this . logger . writeVerbose ( "Already started." ) ;
162
+ return ;
163
+ case SessionStatus . Busy :
164
+ // We're started but busy so notify and return.
165
+ // TODO: Make a proper notification for this and when IntelliSense is blocked.
166
+ this . logger . write ( "The Extension Terminal is currently busy, please wait for your task to finish!" ) ;
167
+ return ;
168
+ case SessionStatus . Stopping :
169
+ // Wait until done stopping, then start.
170
+ this . logger . writeVerbose ( "Still stopping." ) ;
171
+ await this . waitWhileStopping ( ) ;
172
+ break ;
173
+ case SessionStatus . Failed :
174
+ // Try to start again.
175
+ this . logger . writeVerbose ( "Previously failed, starting again." ) ;
176
+ break ;
154
177
}
155
178
156
179
this . setSessionStatus ( "Starting..." , SessionStatus . Starting ) ;
@@ -220,7 +243,7 @@ export class SessionManager implements Middleware {
220
243
}
221
244
}
222
245
223
- public async stop ( ) : Promise < void > {
246
+ private async stop ( ) : Promise < void > {
224
247
this . setSessionStatus ( "Stopping..." , SessionStatus . Stopping ) ;
225
248
// Cancel start-up if we're still waiting.
226
249
this . startCancellationTokenSource ?. cancel ( ) ;
@@ -255,7 +278,7 @@ export class SessionManager implements Middleware {
255
278
this . setSessionStatus ( "Not Started" , SessionStatus . NotStarted ) ;
256
279
}
257
280
258
- public async restartSession ( exeNameOverride ?: string ) : Promise < void > {
281
+ private async restartSession ( exeNameOverride ?: string ) : Promise < void > {
259
282
this . logger . write ( "Restarting session..." ) ;
260
283
await this . stop ( ) ;
261
284
@@ -267,22 +290,18 @@ export class SessionManager implements Middleware {
267
290
}
268
291
269
292
public getSessionDetails ( ) : IEditorServicesSessionDetails | undefined {
270
- // TODO: This is used solely by the debugger and should actually just wait (with a timeout) .
293
+ // This is used by the debugger which should have already called `start` .
271
294
if ( this . sessionDetails === undefined ) {
272
295
void this . logger . writeAndShowError ( "PowerShell session unavailable for debugging!" ) ;
273
296
}
274
297
return this . sessionDetails ;
275
298
}
276
299
277
- public getSessionStatus ( ) : SessionStatus {
278
- return this . sessionStatus ;
279
- }
280
-
281
300
public getPowerShellVersionDetails ( ) : IPowerShellVersionDetails | undefined {
282
301
return this . versionDetails ;
283
302
}
284
303
285
- public getNewSessionFilePath ( ) : vscode . Uri {
304
+ private getNewSessionFilePath ( ) : vscode . Uri {
286
305
const uniqueId : number = Math . floor ( 100000 + Math . random ( ) * 900000 ) ;
287
306
return vscode . Uri . joinPath ( this . sessionsFolder , `PSES-VSCode-${ process . env . VSCODE_PID } -${ uniqueId } .json` ) ;
288
307
}
@@ -334,14 +353,12 @@ export class SessionManager implements Middleware {
334
353
}
335
354
336
355
public async waitUntilStarted ( ) : Promise < void > {
337
- while ( this . sessionStatus === SessionStatus . Starting ) {
338
- if ( this . startCancellationTokenSource ?. token . isCancellationRequested ) {
339
- return ;
340
- }
356
+ while ( this . sessionStatus !== SessionStatus . Running ) {
341
357
await utils . sleep ( 300 ) ;
342
358
}
343
359
}
344
360
361
+ // TODO: Is this used by the magic of "Middleware" in the client library?
345
362
public resolveCodeLens (
346
363
codeLens : vscode . CodeLens ,
347
364
token : vscode . CancellationToken ,
@@ -803,6 +820,21 @@ Type 'help' to get help.
803
820
return languageStatusItem ;
804
821
}
805
822
823
+ private async waitWhileStarting ( ) : Promise < void > {
824
+ while ( this . sessionStatus === SessionStatus . Starting ) {
825
+ if ( this . startCancellationTokenSource ?. token . isCancellationRequested ) {
826
+ return ;
827
+ }
828
+ await utils . sleep ( 300 ) ;
829
+ }
830
+ }
831
+
832
+ private async waitWhileStopping ( ) : Promise < void > {
833
+ while ( this . sessionStatus === SessionStatus . Stopping ) {
834
+ await utils . sleep ( 300 ) ;
835
+ }
836
+ }
837
+
806
838
private setSessionStatus ( detail : string , status : SessionStatus ) : void {
807
839
this . logger . writeVerbose ( `Session status changing from '${ this . sessionStatus } ' to '${ status } '.` ) ;
808
840
this . sessionStatus = status ;
@@ -842,7 +874,6 @@ Type 'help' to get help.
842
874
this . languageStatusItem . severity = vscode . LanguageStatusSeverity . Error ;
843
875
break ;
844
876
}
845
-
846
877
}
847
878
848
879
private setSessionRunningStatus ( ) : void {
@@ -910,7 +941,7 @@ Type 'help' to get help.
910
941
}
911
942
912
943
// Always shows the session terminal.
913
- public showSessionTerminal ( isExecute ?: boolean ) : void {
944
+ private showSessionTerminal ( isExecute ?: boolean ) : void {
914
945
this . languageServerProcess ?. showTerminal ( isExecute && ! this . sessionSettings . integratedConsole . focusConsoleOnExecute ) ;
915
946
}
916
947
0 commit comments