-
Notifications
You must be signed in to change notification settings - Fork 382
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MonitorEventsAsync Progress Action is one event behind #663
Comments
I cloned the repository and created a unit test method for this case in the ISystemOperationsTests class. [Fact]
public async Task MonitorEventsFiltered_Container_StartStop()
{
var createContainerResponse = await _dockerClient.Containers.CreateContainerAsync(
new CreateContainerParameters
{
Image = $"{_repositoryName}:{_tag}"
}
);
var eventParameters = new ContainerEventsParameters
{
Filters = new Dictionary<string, IDictionary<string, bool>>
{
{
"event", new Dictionary<string, bool>
{
{ "start", true },
{ "stop", true },
}
},
{
"type", new Dictionary<string, bool>
{
{ "container", true }
}
},
{
"container", new Dictionary<string, bool>
{
{ createContainerResponse.ID, true },
}
}
}
};
var i = 0;
var eventProgress = new Progress<Message>((message) =>
{
Assert.Equal(createContainerResponse.ID, message.ID);
_output.WriteLine($"Container {createContainerResponse.ID} event: {message.Action}");
if (i == 0)
{
Assert.Equal("start", message.Action);
i++;
}
else if (i == 1)
{
Assert.Equal("stop", message.Action);
}
});
using var cts = CancellationTokenSource.CreateLinkedTokenSource(_cts.Token);
var task = Task.Run(() => _dockerClient.System.MonitorEventsAsync(eventParameters, eventProgress, cts.Token));
await Task.Delay(TimeSpan.FromSeconds(3));
await _dockerClient.Containers.StartContainerAsync(createContainerResponse.ID, new ContainerStartParameters());
await Task.Delay(TimeSpan.FromSeconds(3));
await _dockerClient.Containers.StopContainerAsync(createContainerResponse.ID, new ContainerStopParameters());
await _dockerClient.Containers.RemoveContainerAsync(createContainerResponse.ID, new ContainerRemoveParameters(), cts.Token);
await Task.Delay(TimeSpan.FromSeconds(1));
cts.Cancel();
Assert.Equal(1, i);
Assert.True(task.IsCanceled);
} The test will pass without any problems. Maybe the problem is caused by an Docker Engine API mismatch? I'm not sure about this. |
I've encountered the same issue. I guess it's caused by the JSON deserializer's internal buffering. It works fine with the following workaround: async Task MonitorEventsAsync(IDockerClient client, IProgress<Message> progress, CancellationToken cancellationToken)
{
using var stream = await client.System.MonitorEventsAsync(new ContainerEventsParameters(), cancellationToken);
using var reader = new StreamReader(stream, Encoding.UTF8, false);
while (!cancellationToken.IsCancellationRequested)
{
var line = await reader.ReadLineAsync(cancellationToken);
if (line is null) break;
var msg = System.Text.Json.JsonSerializer.Deserialize<Message>(line);
if (msg is null) continue;
progress.Report(msg);
}
} |
Your method works definitely better then the Docker.DotNet MonitorEventsAsync method. var eventParameters = new ContainerEventsParameters
{
Filters = new Dictionary<string, IDictionary<string, bool>>
{
{
"event", new Dictionary<string, bool>
{
{ "start", true },
{ "stop", true },
{ "destroy", true },
{ "create", true },
}
},
{
"type", new Dictionary<string, bool>
{
{ "containers", true },
}
},
}
}; Running this in the terminal reports everything as it should be |
I stumbled upon this comment #653 (comment) |
You have a typo in your filters. The type should be container not containers. |
Your right! Be careful when renaming variables with the vs2022 shortcut :) |
Output of
dotnet --info
:What version of Docker.DotNet?:
Steps to reproduce the issue:
Start the program and start and stop some container a few times.
What actually happened?:
The first time an container has been stopped or started, nothing happens.
The second time container gets stopped or started, the Progress Action gets executed with the response message from the event before that event.
So if you stopped an container at first and started it in the second step, the program will log
Docker Event stop fired for <your_container_id>.
What did you expect to happen?:
I would expect that when the first event gets triggered, the Progress Action gets executed for that event and not the event that happened before that event.
Additional information:
I think this issue can be considered related: #576
The text was updated successfully, but these errors were encountered: