feat: complete TASK-WP0-08 logging

This commit is contained in:
suyx
2026-07-28 00:11:02 +08:00
parent 096a1f1279
commit 361bda2f22
21 changed files with 1050 additions and 22 deletions
@@ -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();
}