< Summary

Information
Class: Anichron.Worker.Ingestion.Proxy.SystemProcessLauncher
Assembly: Anichron.Worker
File(s): /home/runner/work/anichron/anichron/src/Anichron.Worker/Ingestion/Proxy/ProcessLauncher.cs
Tag: 228_36821334185
Line coverage
0%
Covered lines: 0
Uncovered lines: 26
Coverable lines: 26
Total lines: 49
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 2
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
RunAsync()0%620%

File(s)

/home/runner/work/anichron/anichron/src/Anichron.Worker/Ingestion/Proxy/ProcessLauncher.cs

#LineLine coverage
 1using System.Diagnostics;
 2
 3namespace Anichron.Worker.Ingestion.Proxy;
 4
 5internal interface IProcessLauncher
 6{
 7    Task<ProcessResult> RunAsync(string fileName, IReadOnlyList<string> arguments, CancellationToken ct);
 8}
 9
 10internal sealed record ProcessResult(int ExitCode, string StandardError);
 11
 12internal sealed class SystemProcessLauncher : IProcessLauncher
 13{
 14    public async Task<ProcessResult> RunAsync(string fileName, IReadOnlyList<string> arguments, CancellationToken ct)
 015    {
 016        using var process = new Process();
 017        process.StartInfo = new ProcessStartInfo
 018        {
 019            FileName = fileName,
 020            RedirectStandardOutput = true,
 021            RedirectStandardError = true,
 022            UseShellExecute = false,
 023            CreateNoWindow = true,
 024        };
 025        foreach (var arg in arguments)
 026            process.StartInfo.ArgumentList.Add(arg);
 27
 028        process.Start();
 29        // Start draining pipes immediately — must be consumed to prevent the child process
 30        // from blocking on a full pipe buffer. Cancellation is signalled only via WaitForExitAsync.
 031        var stdoutTask = process.StandardOutput.ReadToEndAsync(CancellationToken.None);
 032        var stderrTask = process.StandardError.ReadToEndAsync(CancellationToken.None);
 33        try
 034        {
 035            await process.WaitForExitAsync(ct);
 036            await stdoutTask;
 037            var standardError = await stderrTask;
 038            return new ProcessResult(process.ExitCode, standardError);
 39        }
 040        catch (OperationCanceledException)
 041        {
 42            // Kill the process tree so GPU encoder children (e.g. vaenc) are not orphaned.
 043            process.Kill(entireProcessTree: true);
 44            // Drain fully before returning — the killed process closes its pipes immediately.
 045            await Task.WhenAll(stdoutTask, stderrTask);
 046            throw;
 47        }
 048    }
 49}

Methods/Properties

RunAsync()