Skip to content

Commit 00a4d2a

Browse files
authored
Startup task tweaks (#1203)
* Improve startup task dispose * Add more logging
1 parent 4c12d38 commit 00a4d2a

File tree

5 files changed

+66
-35
lines changed

5 files changed

+66
-35
lines changed

src/PowerShellEditorServices.Hosting/Commands/StartEditorServicesCommand.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,8 @@ protected override void EndProcessing()
238238
using (var psesLoader = EditorServicesLoader.Create(_logger, editorServicesConfig, sessionFileWriter, _loggerUnsubscribers))
239239
{
240240
_logger.Log(PsesLogLevel.Verbose, "Loading EditorServices");
241-
psesLoader.LoadAndRunEditorServicesAsync().Wait();
241+
// Start editor services and wait here until it shuts down
242+
psesLoader.LoadAndRunEditorServicesAsync().GetAwaiter().GetResult();
242243
}
243244
}
244245
catch (Exception e)
@@ -432,20 +433,20 @@ private ITransportConfig GetLanguageServiceTransport()
432433

433434
if (Stdio)
434435
{
435-
return new StdioTransportConfig();
436+
return new StdioTransportConfig(_logger);
436437
}
437438

438439
if (LanguageServiceInPipeName != null && LanguageServiceOutPipeName != null)
439440
{
440-
return SimplexNamedPipeTransportConfig.Create(LanguageServiceInPipeName, LanguageServiceOutPipeName);
441+
return SimplexNamedPipeTransportConfig.Create(_logger, LanguageServiceInPipeName, LanguageServiceOutPipeName);
441442
}
442443

443444
if (SplitInOutPipes)
444445
{
445-
return SimplexNamedPipeTransportConfig.Create(LanguageServicePipeName);
446+
return SimplexNamedPipeTransportConfig.Create(_logger, LanguageServicePipeName);
446447
}
447448

448-
return DuplexNamedPipeTransportConfig.Create(LanguageServicePipeName);
449+
return DuplexNamedPipeTransportConfig.Create(_logger, LanguageServicePipeName);
449450
}
450451

451452
private ITransportConfig GetDebugServiceTransport()
@@ -456,7 +457,7 @@ private ITransportConfig GetDebugServiceTransport()
456457
{
457458
if (DebugServiceOnly)
458459
{
459-
return new StdioTransportConfig();
460+
return new StdioTransportConfig(_logger);
460461
}
461462

462463
_logger.Log(PsesLogLevel.Diagnostic, "No debug transport: Transport is Stdio with debug disabled");
@@ -465,15 +466,15 @@ private ITransportConfig GetDebugServiceTransport()
465466

466467
if (DebugServiceInPipeName != null && DebugServiceOutPipeName != null)
467468
{
468-
return SimplexNamedPipeTransportConfig.Create(DebugServiceInPipeName, DebugServiceOutPipeName);
469+
return SimplexNamedPipeTransportConfig.Create(_logger, DebugServiceInPipeName, DebugServiceOutPipeName);
469470
}
470471

471472
if (SplitInOutPipes)
472473
{
473-
return SimplexNamedPipeTransportConfig.Create(DebugServicePipeName);
474+
return SimplexNamedPipeTransportConfig.Create(_logger, DebugServicePipeName);
474475
}
475476

476-
return DuplexNamedPipeTransportConfig.Create(DebugServicePipeName);
477+
return DuplexNamedPipeTransportConfig.Create(_logger, DebugServicePipeName);
477478
}
478479

479480
private enum ProfileHostKind

src/PowerShellEditorServices.Hosting/Configuration/HostLogger.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ private void RunWriter()
363363
_fileWriter.WriteLine(logMessage);
364364
}
365365
}
366-
catch (TaskCanceledException)
366+
catch (OperationCanceledException)
367367
{
368368
}
369369
}

src/PowerShellEditorServices.Hosting/Configuration/TransportConfig.cs

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ public interface ITransportConfig
4343
/// </summary>
4444
public sealed class StdioTransportConfig : ITransportConfig
4545
{
46+
private readonly HostLogger _logger;
47+
48+
public StdioTransportConfig(HostLogger logger)
49+
{
50+
_logger = logger;
51+
}
52+
4653
public string EndpointDetails => "<stdio>";
4754

4855
public string SessionFileTransportName => "Stdio";
@@ -51,6 +58,7 @@ public sealed class StdioTransportConfig : ITransportConfig
5158

5259
public Task<(Stream inStream, Stream outStream)> ConnectStreamsAsync()
5360
{
61+
_logger.Log(PsesLogLevel.Diagnostic, "Connecting stdio streams");
5462
return Task.FromResult((Console.OpenStandardInput(), Console.OpenStandardOutput()));
5563
}
5664
}
@@ -64,29 +72,32 @@ public sealed class DuplexNamedPipeTransportConfig : ITransportConfig
6472
/// Create a duplex named pipe transport config with an automatically generated pipe name.
6573
/// </summary>
6674
/// <returns>A new duplex named pipe transport configuration.</returns>
67-
public static DuplexNamedPipeTransportConfig Create()
75+
public static DuplexNamedPipeTransportConfig Create(HostLogger logger)
6876
{
69-
return new DuplexNamedPipeTransportConfig(NamedPipeUtils.GenerateValidNamedPipeName());
77+
return new DuplexNamedPipeTransportConfig(logger, NamedPipeUtils.GenerateValidNamedPipeName());
7078
}
7179

7280
/// <summary>
7381
/// Create a duplex named pipe transport config with the given pipe name.
7482
/// </summary>
7583
/// <returns>A new duplex named pipe transport configuration.</returns>
76-
public static DuplexNamedPipeTransportConfig Create(string pipeName)
84+
public static DuplexNamedPipeTransportConfig Create(HostLogger logger, string pipeName)
7785
{
7886
if (pipeName == null)
7987
{
80-
return DuplexNamedPipeTransportConfig.Create();
88+
return DuplexNamedPipeTransportConfig.Create(logger);
8189
}
8290

83-
return new DuplexNamedPipeTransportConfig(pipeName);
91+
return new DuplexNamedPipeTransportConfig(logger, pipeName);
8492
}
8593

94+
private readonly HostLogger _logger;
95+
8696
private readonly string _pipeName;
8797

88-
private DuplexNamedPipeTransportConfig(string pipeName)
98+
private DuplexNamedPipeTransportConfig(HostLogger logger, string pipeName)
8999
{
100+
_logger = logger;
90101
_pipeName = pipeName;
91102
SessionFileEntries = new Dictionary<string, object>{ { "PipeName", NamedPipeUtils.GetNamedPipePath(pipeName) } };
92103
}
@@ -99,8 +110,11 @@ private DuplexNamedPipeTransportConfig(string pipeName)
99110

100111
public async Task<(Stream inStream, Stream outStream)> ConnectStreamsAsync()
101112
{
113+
_logger.Log(PsesLogLevel.Diagnostic, "Creating named pipe");
102114
NamedPipeServerStream namedPipe = NamedPipeUtils.CreateNamedPipe(_pipeName, PipeDirection.InOut);
115+
_logger.Log(PsesLogLevel.Diagnostic, "Waiting for named pipe connection");
103116
await namedPipe.WaitForConnectionAsync().ConfigureAwait(false);
117+
_logger.Log(PsesLogLevel.Diagnostic, "Named pipe connected");
104118
return (namedPipe, namedPipe);
105119
}
106120
}
@@ -117,42 +131,44 @@ public sealed class SimplexNamedPipeTransportConfig : ITransportConfig
117131
/// Create a pair of simplex named pipes using generated names.
118132
/// </summary>
119133
/// <returns>A new simplex named pipe transport config.</returns>
120-
public static SimplexNamedPipeTransportConfig Create()
134+
public static SimplexNamedPipeTransportConfig Create(HostLogger logger)
121135
{
122-
return SimplexNamedPipeTransportConfig.Create(NamedPipeUtils.GenerateValidNamedPipeName(new[] { InPipePrefix, OutPipePrefix }));
136+
return SimplexNamedPipeTransportConfig.Create(logger, NamedPipeUtils.GenerateValidNamedPipeName(new[] { InPipePrefix, OutPipePrefix }));
123137
}
124138

125139
/// <summary>
126140
/// Create a pair of simplex named pipes using the given name as a base.
127141
/// </summary>
128142
/// <returns>A new simplex named pipe transport config.</returns>
129-
public static SimplexNamedPipeTransportConfig Create(string pipeNameBase)
143+
public static SimplexNamedPipeTransportConfig Create(HostLogger logger, string pipeNameBase)
130144
{
131145
if (pipeNameBase == null)
132146
{
133-
return SimplexNamedPipeTransportConfig.Create();
147+
return SimplexNamedPipeTransportConfig.Create(logger);
134148
}
135149

136150
string inPipeName = $"{InPipePrefix}_{pipeNameBase}";
137151
string outPipeName = $"{OutPipePrefix}_{pipeNameBase}";
138152

139-
return SimplexNamedPipeTransportConfig.Create(inPipeName, outPipeName);
153+
return SimplexNamedPipeTransportConfig.Create(logger, inPipeName, outPipeName);
140154
}
141155

142156
/// <summary>
143157
/// Create a pair of simplex named pipes using the given names.
144158
/// </summary>
145159
/// <returns>A new simplex named pipe transport config.</returns>
146-
public static SimplexNamedPipeTransportConfig Create(string inPipeName, string outPipeName)
160+
public static SimplexNamedPipeTransportConfig Create(HostLogger logger, string inPipeName, string outPipeName)
147161
{
148-
return new SimplexNamedPipeTransportConfig(inPipeName, outPipeName);
162+
return new SimplexNamedPipeTransportConfig(logger, inPipeName, outPipeName);
149163
}
150164

165+
private readonly HostLogger _logger;
151166
private readonly string _inPipeName;
152167
private readonly string _outPipeName;
153168

154-
private SimplexNamedPipeTransportConfig(string inPipeName, string outPipeName)
169+
private SimplexNamedPipeTransportConfig(HostLogger logger, string inPipeName, string outPipeName)
155170
{
171+
_logger = logger;
156172
_inPipeName = inPipeName;
157173
_outPipeName = outPipeName;
158174

@@ -171,14 +187,18 @@ private SimplexNamedPipeTransportConfig(string inPipeName, string outPipeName)
171187

172188
public async Task<(Stream inStream, Stream outStream)> ConnectStreamsAsync()
173189
{
190+
_logger.Log(PsesLogLevel.Diagnostic, "Starting in pipe connection");
174191
NamedPipeServerStream inPipe = NamedPipeUtils.CreateNamedPipe(_inPipeName, PipeDirection.InOut);
175192
Task inPipeConnected = inPipe.WaitForConnectionAsync();
176193

194+
_logger.Log(PsesLogLevel.Diagnostic, "Starting out pipe connection");
177195
NamedPipeServerStream outPipe = NamedPipeUtils.CreateNamedPipe(_outPipeName, PipeDirection.Out);
178196
Task outPipeConnected = outPipe.WaitForConnectionAsync();
179197

198+
_logger.Log(PsesLogLevel.Diagnostic, "Wating for pipe connections");
180199
await Task.WhenAll(inPipeConnected, outPipeConnected).ConfigureAwait(false);
181200

201+
_logger.Log(PsesLogLevel.Diagnostic, "Simplex named pipe transport connected");
182202
return (inPipe, outPipe);
183203
}
184204
}

src/PowerShellEditorServices.Hosting/EditorServicesLoader.cs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ public static EditorServicesLoader Create(
160160

161161
private readonly IReadOnlyCollection<IDisposable> _loggersToUnsubscribe;
162162

163+
private EditorServicesRunner _editorServicesRunner;
164+
163165
private EditorServicesLoader(
164166
HostLogger logger,
165167
EditorServicesConfig hostConfig,
@@ -177,7 +179,7 @@ private EditorServicesLoader(
177179
/// This method's returned task will end when Editor Services shuts down.
178180
/// </summary>
179181
/// <returns></returns>
180-
public async Task LoadAndRunEditorServicesAsync()
182+
public Task LoadAndRunEditorServicesAsync()
181183
{
182184
// Log important host information here
183185
LogHostInformation();
@@ -200,22 +202,27 @@ public async Task LoadAndRunEditorServicesAsync()
200202
LoadEditorServices();
201203

202204
_logger.Log(PsesLogLevel.Verbose, "Starting EditorServices");
203-
using (var editorServicesRunner = new EditorServicesRunner(_logger, _hostConfig, _sessionFileWriter, _loggersToUnsubscribe))
204-
{
205-
// The trigger method for Editor Services
206-
// We will wait here until Editor Services shuts down
207-
await editorServicesRunner.RunUntilShutdown().ConfigureAwait(false);
208-
}
205+
206+
_editorServicesRunner = new EditorServicesRunner(_logger, _hostConfig, _sessionFileWriter, _loggersToUnsubscribe);
207+
208+
// The trigger method for Editor Services
209+
return Task.Run(_editorServicesRunner.RunUntilShutdown);
209210
}
210211

211212
public void Dispose()
212213
{
213-
// TODO: Remove assembly resolve events
214-
// This is not high priority, since the PSES process shouldn't be reused
214+
_logger.Log(PsesLogLevel.Diagnostic, "Loader disposed");
215+
_editorServicesRunner?.Dispose();
216+
217+
// TODO:
218+
// Remove assembly resolve events
219+
// This is not high priority, since the PSES process shouldn't be reused
215220
}
216221

217222
private void LoadEditorServices()
218223
{
224+
// This must be in its own method, since the actual load happens when the calling method is called
225+
// The call within this method is therefore a total no-op
219226
EditorServicesLoading.LoadEditorServicesForHost();
220227
}
221228

src/PowerShellEditorServices.Hosting/Internal/EditorServicesRunner.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public EditorServicesRunner(
4747
/// Start and run Editor Services and then wait for shutdown.
4848
/// </summary>
4949
/// <returns>A task that ends when Editor Services shuts down.</returns>
50-
public async Task RunUntilShutdown()
50+
public Task RunUntilShutdown()
5151
{
5252
// Start Editor Services
5353
Task runAndAwaitShutdown = CreateEditorServicesAndRunUntilShutdown();
@@ -57,7 +57,8 @@ public async Task RunUntilShutdown()
5757
_sessionFileWriter.WriteSessionStarted(_config.LanguageServiceTransport, _config.DebugServiceTransport);
5858

5959
// Finally, wait for Editor Services to shut down
60-
await runAndAwaitShutdown.ConfigureAwait(false);
60+
_logger.Log(PsesLogLevel.Diagnostic, "Waiting on PSES run/shutdown");
61+
return runAndAwaitShutdown;
6162
}
6263

6364
public void Dispose()
@@ -73,6 +74,8 @@ private async Task CreateEditorServicesAndRunUntilShutdown()
7374
{
7475
try
7576
{
77+
_logger.Log(PsesLogLevel.Diagnostic, "Creating/running editor services");
78+
7679
bool creatingLanguageServer = _config.LanguageServiceTransport != null;
7780
bool creatingDebugServer = _config.DebugServiceTransport != null;
7881
bool isTempDebugSession = creatingDebugServer && !creatingLanguageServer;

0 commit comments

Comments
 (0)