Skip to content

Instantly share code, notes, and snippets.

@dgvives
Created February 17, 2021 22:18
Show Gist options
  • Save dgvives/2620960049191797ea0d871c339d9bc2 to your computer and use it in GitHub Desktop.
Save dgvives/2620960049191797ea0d871c339d9bc2 to your computer and use it in GitHub Desktop.
MultiplexedStreamReader can be cancelled cancellation
using System;
using System.Threading;
using System.Threading.Tasks;
using Docker.DotNet;
using Docker.DotNet.Models;
using Xunit.Abstractions;
namespace TesterApp
{
public class tester : IDisposable
{
private readonly CancellationTokenSource _cts;
private readonly DockerClient _dockerClient;
private readonly string _imageId;
private readonly TestOutput _output = new TestOutput();
public tester()
{
using var configuration = new DockerClientConfiguration();
_dockerClient = configuration.CreateClient();
_cts = new CancellationTokenSource();
_imageId = "hello-world";
}
public void Dispose()
{
_dockerClient.Dispose();
_cts.Dispose();
}
public async Task GetContainerLogs()
{
using var containerLogsCts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
var tcs = new TaskCompletionSource<string>(containerLogsCts.Token);
using (containerLogsCts.Token.Register(() => tcs.SetCanceled())) ;
await _dockerClient.Images.CreateImageAsync(new ImagesCreateParameters { FromImage = "hello-world:latest" }, null, new Progress<JSONMessage>(), default);
var createContainerResponse = await _dockerClient.Containers.CreateContainerAsync(
new CreateContainerParameters()
{
Image = _imageId,
Name = Guid.NewGuid().ToString()
},
_cts.Token
);
await _dockerClient.Containers.StartContainerAsync(
createContainerResponse.ID,
new ContainerStartParameters(),
_cts.Token
);
await _dockerClient.Containers.StopContainerAsync(
createContainerResponse.ID,
new ContainerStopParameters(),
_cts.Token
);
var multiplexedStream = await _dockerClient.Containers.GetContainerLogsAsync(
id: createContainerResponse.ID,
tty: true,
new ContainerLogsParameters
{
ShowStderr = true,
ShowStdout = true,
Timestamps = true
},
containerLogsCts.Token
);
var multiReader = new MultiplexedStreamReader(multiplexedStream);
while (!containerLogsCts.IsCancellationRequested)
{
var line = await multiReader.ReadLineAsync(containerLogsCts.Token);
if (string.IsNullOrEmpty(line))
break;
_output.WriteLine($"Multiplexed stream read: '{line}'");
}
}
public async Task GetContainerLogs_ReadMultiplexedStream()
{
var createContainerResponse = await _dockerClient.Containers.CreateContainerAsync(
new CreateContainerParameters()
{
Image = _imageId,
Name = Guid.NewGuid().ToString()
},
_cts.Token
);
await _dockerClient.Containers.StartContainerAsync(
createContainerResponse.ID,
new ContainerStartParameters(),
_cts.Token
);
var logsStream = await _dockerClient.Containers.GetContainerLogsAsync(
createContainerResponse.ID,
tty: true,
new ContainerLogsParameters
{
ShowStderr = true,
ShowStdout = true,
Timestamps = true
},
_cts.Token
);
var logs = await logsStream.ReadOutputToEndAsync(_cts.Token);
_output.WriteLine(logs.stdout);
Assert.NotEmpty(logs.stdout);
}
}
public class TestOutput
{
private readonly ITestOutputHelper _outputHelper;
public TestOutput(ITestOutputHelper outputHelper = null)
{
_outputHelper = outputHelper;
}
public void WriteLine(string line)
{
Console.WriteLine(line);
_outputHelper?.WriteLine(line);
System.Diagnostics.Debug.WriteLine(line);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment