Skip to content

Commit 27a1735

Browse files
committed
Reinstate runspace cleanup logic
1 parent 1f52dde commit 27a1735

File tree

1 file changed

+37
-22
lines changed

1 file changed

+37
-22
lines changed

src/PowerShellEditorServices/Services/PowerShell/Host/PsesInternalHost.cs

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ internal class PsesInternalHost : PSHost, IHostSupportsInteractiveSession, IRuns
6363

6464
private bool _skipNextPrompt = false;
6565

66+
private bool _resettingRunspace = false;
67+
6668
public PsesInternalHost(
6769
ILoggerFactory loggerFactory,
6870
ILanguageServerFacade languageServer,
@@ -343,13 +345,19 @@ public Task SetInitialWorkingDirectoryAsync(string path, CancellationToken cance
343345

344346
private void Run()
345347
{
346-
SMA.PowerShell pwsh = CreateInitialPowerShell(_hostInfo, _readLineProvider);
347-
RunspaceInfo localRunspaceInfo = RunspaceInfo.CreateFromLocalPowerShell(_logger, pwsh);
348+
(PowerShell pwsh, RunspaceInfo localRunspaceInfo) = CreateInitialPowerShellSession();
348349
_localComputerName = localRunspaceInfo.SessionDetails.ComputerName;
349350
_runspaceStack.Push(new RunspaceFrame(pwsh.Runspace, localRunspaceInfo));
350351
PushPowerShellAndRunLoop(pwsh, PowerShellFrameType.Normal, localRunspaceInfo);
351352
}
352353

354+
private (PowerShell, RunspaceInfo) CreateInitialPowerShellSession()
355+
{
356+
PowerShell pwsh = CreateInitialPowerShell(_hostInfo, _readLineProvider);
357+
RunspaceInfo localRunspaceInfo = RunspaceInfo.CreateFromLocalPowerShell(_logger, pwsh);
358+
return (pwsh, localRunspaceInfo);
359+
}
360+
353361
private void PushPowerShellAndRunLoop(SMA.PowerShell pwsh, PowerShellFrameType frameType, RunspaceInfo newRunspaceInfo = null)
354362
{
355363
// TODO: Improve runspace origin detection here
@@ -392,14 +400,7 @@ private RunspaceInfo GetRunspaceInfoForPowerShell(SMA.PowerShell pwsh, out bool
392400

393401
private void PushPowerShellAndRunLoop(PowerShellContextFrame frame)
394402
{
395-
if (_psFrameStack.Count > 0)
396-
{
397-
RemoveRunspaceEventHandlers(CurrentFrame.PowerShell.Runspace);
398-
}
399-
400-
AddRunspaceEventHandlers(frame.PowerShell.Runspace);
401-
402-
_psFrameStack.Push(frame);
403+
PushPowerShell(frame);
403404

404405
try
405406
{
@@ -422,7 +423,19 @@ private void PushPowerShellAndRunLoop(PowerShellContextFrame frame)
422423
}
423424
}
424425

425-
private void PopPowerShell()
426+
private void PushPowerShell(PowerShellContextFrame frame)
427+
{
428+
if (_psFrameStack.Count > 0)
429+
{
430+
RemoveRunspaceEventHandlers(CurrentFrame.PowerShell.Runspace);
431+
}
432+
433+
AddRunspaceEventHandlers(frame.PowerShell.Runspace);
434+
435+
_psFrameStack.Push(frame);
436+
}
437+
438+
private void PopPowerShell(RunspaceChangeAction runspaceChangeAction = RunspaceChangeAction.Exit)
426439
{
427440
_shouldExit = false;
428441
PowerShellContextFrame frame = _psFrameStack.Pop();
@@ -436,7 +449,7 @@ private void PopPowerShell()
436449
RunspaceFrame currentRunspaceFrame = _runspaceStack.Peek();
437450
RemoveRunspaceEventHandlers(previousRunspaceFrame.Runspace);
438451
AddRunspaceEventHandlers(currentRunspaceFrame.Runspace);
439-
RunspaceChanged?.Invoke(this, new RunspaceChangedEventArgs(RunspaceChangeAction.Exit, previousRunspaceFrame.RunspaceInfo, currentRunspaceFrame.RunspaceInfo));
452+
RunspaceChanged?.Invoke(this, new RunspaceChangedEventArgs(runspaceChangeAction, previousRunspaceFrame.RunspaceInfo, currentRunspaceFrame.RunspaceInfo));
440453
}
441454
}
442455
finally
@@ -730,37 +743,40 @@ private void OnBreakpointUpdated(object sender, BreakpointUpdatedEventArgs break
730743

731744
private void OnRunspaceStateChanged(object sender, RunspaceStateEventArgs runspaceStateEventArgs)
732745
{
733-
if (!_shouldExit && !runspaceStateEventArgs.RunspaceStateInfo.IsUsable())
746+
if (!_shouldExit && !_resettingRunspace && !runspaceStateEventArgs.RunspaceStateInfo.IsUsable())
734747
{
735-
//PopOrReinitializeRunspaceAsync();
748+
_resettingRunspace = true;
749+
PopOrReinitializeRunspaceAsync().HandleErrorsAsync(_logger);
736750
}
737751
}
738752

739-
/*
740-
private void PopOrReinitializeRunspace()
753+
private Task PopOrReinitializeRunspaceAsync()
741754
{
742-
SetExit();
755+
_cancellationContext.CancelCurrentTaskStack();
743756
RunspaceStateInfo oldRunspaceState = CurrentPowerShell.Runspace.RunspaceStateInfo;
744757

745758
// Rather than try to lock the PowerShell executor while we alter its state,
746759
// we simply run this on its thread, guaranteeing that no other action can occur
747-
_executor.InvokeDelegate(
748-
nameof(PopOrReinitializeRunspace),
760+
return ExecuteDelegateAsync(
761+
nameof(PopOrReinitializeRunspaceAsync),
749762
new ExecutionOptions { InterruptCurrentForeground = true },
750763
(cancellationToken) =>
751764
{
752765
while (_psFrameStack.Count > 0
753766
&& !_psFrameStack.Peek().PowerShell.Runspace.RunspaceStateInfo.IsUsable())
754767
{
755-
PopPowerShell();
768+
PopPowerShell(RunspaceChangeAction.Shutdown);
756769
}
757770

771+
_resettingRunspace = false;
772+
758773
if (_psFrameStack.Count == 0)
759774
{
760775
// If our main runspace was corrupted,
761776
// we must re-initialize our state.
762777
// TODO: Use runspace.ResetRunspaceState() here instead
763-
PushInitialPowerShell();
778+
(PowerShell pwsh, RunspaceInfo runspaceInfo) = CreateInitialPowerShellSession();
779+
PushPowerShell(new PowerShellContextFrame(pwsh, runspaceInfo, PowerShellFrameType.Normal));
764780

765781
_logger.LogError($"Top level runspace entered state '{oldRunspaceState.State}' for reason '{oldRunspaceState.Reason}' and was reinitialized."
766782
+ " Please report this issue in the PowerShell/vscode-PowerShell GitHub repository with these logs.");
@@ -776,7 +792,6 @@ private void PopOrReinitializeRunspace()
776792
},
777793
CancellationToken.None);
778794
}
779-
*/
780795

781796
private record RunspaceFrame(
782797
Runspace Runspace,

0 commit comments

Comments
 (0)