feat: complete TASK-WP0-08 logging
This commit is contained in:
@@ -8,18 +8,32 @@ internal sealed class ManagedChildProcess : IAsyncDisposable
|
||||
{
|
||||
private readonly NamedPipeServerStream controlPipe;
|
||||
private readonly StreamWriter controlWriter;
|
||||
private readonly StreamReader controlReader;
|
||||
private Action<string>? statusReceived;
|
||||
private bool stopping;
|
||||
|
||||
private ManagedChildProcess(Process process, NamedPipeServerStream controlPipe, StreamWriter controlWriter)
|
||||
private ManagedChildProcess(Process process, NamedPipeServerStream controlPipe, StreamReader controlReader, StreamWriter controlWriter)
|
||||
{
|
||||
Process = process;
|
||||
this.controlPipe = controlPipe;
|
||||
this.controlReader = controlReader;
|
||||
this.controlWriter = controlWriter;
|
||||
_ = ListenForStatusAsync();
|
||||
}
|
||||
|
||||
internal Process Process { get; }
|
||||
internal bool IsStopping => stopping;
|
||||
internal static TimeSpan ShutdownDeadline { get; } = TimeSpan.FromSeconds(15);
|
||||
internal string? LastStatus { get; private set; }
|
||||
internal event Action<string> StatusReceived
|
||||
{
|
||||
add
|
||||
{
|
||||
statusReceived += value;
|
||||
if (LastStatus is not null) value(LastStatus);
|
||||
}
|
||||
remove => statusReceived -= value;
|
||||
}
|
||||
|
||||
internal static async Task<ManagedChildProcess> StartAsync(
|
||||
ProcessStartInfo startInfo,
|
||||
@@ -48,7 +62,7 @@ internal sealed class ManagedChildProcess : IAsyncDisposable
|
||||
var ready = await reader.ReadLineAsync(timeout.Token);
|
||||
if (!string.Equals(ready, "ready", StringComparison.Ordinal)) throw new InvalidOperationException("Managed child did not report ready.");
|
||||
var writer = new StreamWriter(pipe, new UTF8Encoding(false), leaveOpen: true) { AutoFlush = true };
|
||||
return new ManagedChildProcess(process, pipe, writer);
|
||||
return new ManagedChildProcess(process, pipe, reader, writer);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -59,6 +73,23 @@ internal sealed class ManagedChildProcess : IAsyncDisposable
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ListenForStatusAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
while (controlPipe.IsConnected && !Process.HasExited)
|
||||
{
|
||||
var status = await controlReader.ReadLineAsync();
|
||||
if (status is null) return;
|
||||
LastStatus = status;
|
||||
statusReceived?.Invoke(status);
|
||||
}
|
||||
}
|
||||
catch (IOException) when (stopping || Process.HasExited)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
internal async Task StopAsync(TimeSpan? timeout = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (stopping || Process.HasExited) return;
|
||||
@@ -77,6 +108,7 @@ internal sealed class ManagedChildProcess : IAsyncDisposable
|
||||
{
|
||||
if (!Process.HasExited) await StopAsync();
|
||||
controlWriter.Dispose();
|
||||
controlReader.Dispose();
|
||||
controlPipe.Dispose();
|
||||
Process.Dispose();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user