Code Monkey home page Code Monkey logo

Comments (6)

noelex avatar noelex commented on June 1, 2024 2

You have a typo in your filters. The type should be container not containers.

from docker.dotnet.

noelex avatar noelex commented on June 1, 2024 1

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);
    }
}

from docker.dotnet.

kosimas avatar kosimas commented on June 1, 2024

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'm using Docker Desktop 4.25.2 on an Windows 11 machine.
I tested it(in the console app not in the unit test) with an npipe connection and I also tried enabling the tcp daemon. The results with the tcp daemon are the same as with an npipe connection.

from docker.dotnet.

kosimas avatar kosimas commented on June 1, 2024

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.
However if I change the Filters to the code below below, your method is reporting nothing anymore.
This leads me to think that even the Obsolete MonitorEventsAsync method has its flaws.

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 docker events --filter 'type=container' --filter 'event=start' --filter 'event=stop' --filter 'event=create' --filter 'event=destroy' --format 'Type={{.Type}} Status={{.Status}} ID={{.ID}}'

from docker.dotnet.

kosimas avatar kosimas commented on June 1, 2024

I stumbled upon this comment #653 (comment)
This is an important information for this issue I think.

from docker.dotnet.

kosimas avatar kosimas commented on June 1, 2024

Your right! Be careful when renaming variables with the vs2022 shortcut :)

from docker.dotnet.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.