private void DebugServer_OnSessionEnded(object sender, EventArgs args) { _logger.Log(PsesLogLevel.Verbose, "Debug session ended, restarting debug service..."); PsesDebugServer oldServer = (PsesDebugServer)sender; oldServer.Dispose(); _alreadySubscribedDebug = false; Task.Run(() => RestartDebugServerAsync(oldServer)); }
private void DebugServer_OnSessionEnded(object sender, EventArgs args) { _logger.Log(PsesLogLevel.Verbose, "Debug session ended, restarting debug service..."); PsesDebugServer oldServer = (PsesDebugServer)sender; oldServer.Dispose(); _alreadySubscribedDebug = false; Task.Run(() => { RestartDebugServerAsync(oldServer, usePSReadLine: _config.ConsoleRepl == ConsoleReplKind.PSReadLine); }); }
/// <summary> /// Starts the debug service with the specified config. /// </summary> /// <param name="config">The config that contains information on the communication protocol that will be used.</param> /// <param name="profilePaths">The profiles that will be loaded in the session.</param> /// <param name="useTempSession">Determines if we will make a new session typically used for temporary console debugging.</param> public void StartDebugService( EditorServiceTransportConfig config, ProfilePaths profilePaths, bool useTempSession) { _logger.LogInformation($"Debug NamedPipe: {config.InOutPipeName}\nDebug OutPipe: {config.OutPipeName}"); IServiceProvider serviceProvider = null; if (useTempSession) { serviceProvider = new ServiceCollection() .AddLogging(builder => builder .ClearProviders() .AddSerilog() .SetMinimumLevel(LogLevel.Trace)) .AddSingleton <ILanguageServer>(provider => null) .AddPsesLanguageServices( profilePaths, _featureFlags, _enableConsoleRepl, _useLegacyReadLine, _internalHost, _hostDetails, _additionalModules) .BuildServiceProvider(); } switch (config.TransportType) { case EditorServiceTransportType.NamedPipe: NamedPipeServerStream inNamedPipe = CreateNamedPipe( config.InOutPipeName ?? config.InPipeName, config.OutPipeName, out NamedPipeServerStream outNamedPipe); _debugServer = new PsesDebugServer( _factory, inNamedPipe, outNamedPipe ?? inNamedPipe); Task[] tasks = outNamedPipe != null ? new[] { inNamedPipe.WaitForConnectionAsync(), outNamedPipe.WaitForConnectionAsync() } : new[] { inNamedPipe.WaitForConnectionAsync() }; Task.WhenAll(tasks) .ContinueWith(async task => { _logger.LogInformation("Starting debug server"); await _debugServer.StartAsync(serviceProvider ?? _languageServer.LanguageServer.Services, useTempSession); _logger.LogInformation( $"Debug service started, type = {config.TransportType}, endpoint = {config.Endpoint}"); }); break; case EditorServiceTransportType.Stdio: _debugServer = new PsesDebugServer( _factory, Console.OpenStandardInput(), Console.OpenStandardOutput()); _logger.LogInformation("Starting debug server"); Task.Run(async() => { await _debugServer.StartAsync(serviceProvider ?? _languageServer.LanguageServer.Services, useTempSession); _logger.LogInformation( $"Debug service started, type = {config.TransportType}, endpoint = {config.Endpoint}"); }); break; default: throw new NotSupportedException($"The transport {config.TransportType} is not supported"); } // If the instance of PSES is being used for debugging only, then we don't want to allow automatic restarting // because the user can simply spin up a new PSES if they need to. // This design decision was done since this "debug-only PSES" is used in the "Temporary Integrated Console debugging" // feature which does not want PSES to be restarted so that the user can see the output of the last debug // session. if (!alreadySubscribedDebug && !useTempSession) { alreadySubscribedDebug = true; _debugServer.SessionEnded += (sender, eventArgs) => { _debugServer.Dispose(); alreadySubscribedDebug = false; StartDebugService(config, profilePaths, useTempSession); }; } }