using System.Diagnostics; namespace ServiceUpdater; public sealed class UpdateWorker(UpdaterConfig config) { private int LastExitCode { get; set; } public async IAsyncEnumerable UpdateService(string serviceName) { yield return $"Starting update for {serviceName}"; await foreach (var line in RunProcess(serviceName, "compose pull")) { yield return line; } if (LastExitCode != 0) yield break; yield return $"Downloaded changes for {serviceName}"; await foreach (var line in RunProcess(serviceName, "compose up -d --remove-orphans")) { yield return line; } } private async IAsyncEnumerable RunProcess(string folder, string arguments) { var process = new Process { StartInfo = new() { FileName = "docker", Arguments = arguments, RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, WorkingDirectory = Path.Combine(config.ServicesRoot, folder) } }; process.Start(); var output = process.StandardOutput.ReadLineAsync(); var error = process.StandardError.ReadLineAsync(); while (true) { var completed = await Task.WhenAny(output, error); if (completed == output) { var line = await output; if (line == null) break; yield return line; output = process.StandardOutput.ReadLineAsync(); } else { var line = await error; if (line == null) break; yield return line; error = process.StandardError.ReadLineAsync(); } } await process.WaitForExitAsync(); LastExitCode = process.ExitCode; } }