zcbot/windows-node/Zcbot.WindowsNode/Adapters/ProcessSupervisor.cs

50 lines
1.5 KiB
C#

using System.Diagnostics;
using System.IO;
using System.Text;
namespace Zcbot.WindowsNode;
internal sealed class ProcessSupervisor
{
internal Process Start(
ProcessStartInfo startInfo,
string failureMessage = "Adapter worker did not start.") =>
Process.Start(startInfo)
?? throw new InvalidOperationException(failureMessage);
internal async Task TerminateTreeAsync(
Process process,
CancellationToken cancellationToken = default)
{
if (process.HasExited) return;
process.Kill(entireProcessTree: true);
using var timeout = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
timeout.CancelAfter(TimeSpan.FromSeconds(30));
try
{
await process.WaitForExitAsync(timeout.Token);
}
catch (OperationCanceledException exception) when (!cancellationToken.IsCancellationRequested)
{
throw new InvalidOperationException(
"Adapter worker process tree did not terminate within 30 seconds.", exception);
}
}
internal async Task<string> CaptureOutputAsync(
StreamReader reader,
IProgress<string>? progress = null)
{
var output = new StringBuilder();
while (await reader.ReadLineAsync() is { } line)
{
if (output.Length < 16 * 1024)
{
output.AppendLine(line);
}
progress?.Report(line);
}
return output.ToString();
}
}