diff --git a/src/Microsoft.Tye.Core/ProcessUtil.cs b/src/Microsoft.Tye.Core/ProcessUtil.cs index df1c8355..a2d65090 100644 --- a/src/Microsoft.Tye.Core/ProcessUtil.cs +++ b/src/Microsoft.Tye.Core/ProcessUtil.cs @@ -114,9 +114,12 @@ namespace Microsoft.Tye process.Exited += (_, e) => { - // Even though the Exited event has been raised, WaitForExit() must still be called to ensure the output buffers - // have been flushed before the process is considered completely done. - process.WaitForExit(); + lock (process) + { + // Even though the Exited event has been raised, WaitForExit() must still be called to ensure the output buffers + // have been flushed before the process is considered completely done. + process.WaitForExit(); + } if (throwOnError && process.ExitCode != 0) { @@ -128,11 +131,15 @@ namespace Microsoft.Tye } }; - process.Start(); - onStart?.Invoke(process.Id); + // lock ensures we're reading output when WaitForExit is called in process.Exited event. + lock (process) + { + process.Start(); + onStart?.Invoke(process.Id); - process.BeginOutputReadLine(); - process.BeginErrorReadLine(); + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + } var cancelledTcs = new TaskCompletionSource(); await using var _ = cancellationToken.Register(() => cancelledTcs.TrySetResult(null)); diff --git a/src/Microsoft.Tye.Hosting/DockerRunner.cs b/src/Microsoft.Tye.Hosting/DockerRunner.cs index 16e0516e..ba193b69 100644 --- a/src/Microsoft.Tye.Hosting/DockerRunner.cs +++ b/src/Microsoft.Tye.Hosting/DockerRunner.cs @@ -311,16 +311,17 @@ namespace Microsoft.Tye.Hosting status.DockerNetwork = dockerNetwork; WriteReplicaToStore(replica); + var stderr = new StringBuilder(); var result = await application.ContainerEngine.RunAsync( command, throwOnError: false, cancellationToken: cancellationToken, outputDataReceived: data => service.Logs.OnNext($"[{replica}]: {data}"), - errorDataReceived: data => service.Logs.OnNext($"[{replica}]: {data}")); + errorDataReceived: data => { service.Logs.OnNext($"[{replica}]: {data}"); stderr.AppendLine(data); }); if (result.ExitCode != 0) { - _logger.LogError("docker run failed for {ServiceName} with exit code {ExitCode}:" + result.StandardError, service.Description.Name, result.ExitCode); + _logger.LogError("docker run failed for {ServiceName} with exit code {ExitCode}: " + stderr, service.Description.Name, result.ExitCode); service.Replicas.TryRemove(replica, out var _); service.ReplicaEvents.OnNext(new ReplicaEvent(ReplicaState.Removed, status));