private async Task RunTempDebugSessionAsync(HostStartupInfo hostDetails) { _logger.Log(PsesLogLevel.Diagnostic, "Running temp debug session"); PsesDebugServer debugServer = await CreateDebugServerForTempSessionAsync(hostDetails).ConfigureAwait(false); _logger.Log(PsesLogLevel.Verbose, "Debug server created"); await debugServer.StartAsync().ConfigureAwait(false); _logger.Log(PsesLogLevel.Verbose, "Debug server started"); await debugServer.WaitForShutdown().ConfigureAwait(false); }
private async Task StartDebugServer(Task <PsesDebugServer> debugServerCreation) { PsesDebugServer debugServer = await debugServerCreation.ConfigureAwait(false); // When the debug server shuts down, we want it to automatically restart // To do this, we set an event to allow it to create a new debug server as its session ends if (!_alreadySubscribedDebug) { _logger.Log(PsesLogLevel.Diagnostic, "Subscribing debug server for session ended event"); _alreadySubscribedDebug = true; debugServer.SessionEnded += DebugServer_OnSessionEnded; } _logger.Log(PsesLogLevel.Diagnostic, "Starting debug server"); debugServer.StartAsync(); }
/// <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); }; } }