Skip to content
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

Docker Daemon Event Reception Support #129

Closed
seertenedos opened this issue Nov 8, 2019 · 6 comments
Closed

Docker Daemon Event Reception Support #129

seertenedos opened this issue Nov 8, 2019 · 6 comments
Labels
enhancement help wanted under-development Denotes that a issue is under development but not yet released.
Milestone

Comments

@seertenedos
Copy link

This is more a guidance question.
What i want to acheave is something like an enhanced docker compose file. I need to define multiple containters that have dependancies between them. I don't want to start a container that has a dependancy until all containers it has a dependancy on have successfully started including been healthy and passing the WaitForXXX checks on the instance start ups. Ideally i would love to be able to specify an action to happen on dependat containers so that if say a container you have a dependancy on is unhealthy, stops or does not pass the staryup checks then the containers dependant on it has the action called on them (stop, pause, remove.)

Sort of like a system where parts of them system comes and goes based on things they are dependant on being available or not and events or something triggering them to be distroyed or recreated as things change.

I thought of building most of it up in code but there is no event that i could see for when a container has passed all the "WaitForxxx" checks which you would need if you wanted this to work via an eventing system including when a container is auto restarted etc.

@mariotoffia
Copy link
Owner

Hi,
My initial thought that the first paragraph is realisable with some form of effort. You have to subscribe to state changes etc to determine the programmatic state of the container service. Very much so e.g. the WaitForProcess et..al injects itself. However, built-in dependency mechanism would be interesting to incorporate at some point in the fluent APIs.

Below taken from the

ContainerBuilder.AddHooks(IService container)
if (null != _config.CpToOnStart)
        container.AddHook(ServiceRunningState.Starting,
          service =>
          {
            Fd.DisposeOnException(svc =>
            {
              foreach (var copy in _config.CpToOnStart)
                ((IContainerService)service).CopyTo(copy.Item2, copy.Item1);
            }, service, "Copy on start");
          });

      // Wait for port when started
      if (null != _config.WaitForPort)
        container.AddHook(ServiceRunningState.Running,
          service =>
          {
            Fd.DisposeOnException(svc =>
                ((IContainerService)service).WaitForPort(_config.WaitForPort.Item1, _config.WaitForPort.Item3,
                  _config.WaitForPort.Item2),
              service, "Wait for port");
          });

      // Wait for healthy when started
      if (null != _config.WaitForHealthy)
        container.AddHook(ServiceRunningState.Running,
          service =>
          {
            Fd.DisposeOnException(svc =>
                ((IContainerService)service).WaitForHealthy(_config.WaitForHealthy.Item1),
              service, "Wait for healthy");
          });

As a side note I'm thinking on having a property on the IContainerService itself to denote the health status and add the same ability to hook into each Health State to invoke custom actions.

What you describe later on will absolutely need to hook into the Events(...) on each of the container. Today it is just a command in the ClientStream along with tailing the logs from one or more containers.

I've been loosely thinking of that one may put a IContainerService under a sponsor (running as a ´Task`) that listens for events and logs, that makes the object react to the container. This is put forward in time since I've strived as much as possible to make this project as simple as possible and this will open up a whole slew of library and user bugs to support. But it is in the roadmap (in my head) amongst other things.

It you're willing to experiment I'm really happy if you could share your code and thoughts!

Cheers,
Mario

@mariotoffia mariotoffia added this to the 4.0.0 milestone Nov 8, 2019
@mariotoffia mariotoffia removed this from the 4.0.0 milestone Nov 8, 2019
@seertenedos
Copy link
Author

Thanks this is something i will play with an share assuming i can get it to work how i want it to or if it atleast has something useful in it.

@mariotoffia
Copy link
Owner

I've merged a first round of event mapping so it is possible to listen on the event stream. A few events has been mapped, I need to do tests to have the runtime emit the different events (since not documented) and make them strongly typed. If it can't recognize a event it creates a UnknownEvent with attributes that it does not know how to handle as a list of key values.

Simple example to iterate a event stream until a ContainerStartedEvent is retrieved.

 using (var events = Fd.Native().Events())
      {
        using (
            var container =
                new Builder().UseContainer()
                    .UseImage("postgres:9.6-alpine")
                    .ExposePort(5432)
                    .WithEnvironment("POSTGRES_PASSWORD=mysecretpassword")
                    .WaitForPort("5432/tcp", 30000 /*30s*/)
                    .Build()
                    .Start())
        {
          FdEvent e;
          while ((e= events.TryRead(3000)) != null)
          {
            if (e.Type == EventType.Container && e.Action == EventAction.Start)
              break;
          }
        }
      }

This is published as beta on nuget if you want to try it out.

@mariotoffia mariotoffia added the under-development Denotes that a issue is under development but not yet released. label Nov 12, 2019
@mariotoffia mariotoffia added this to the 3.0.0 milestone Nov 12, 2019
@seertenedos
Copy link
Author

seertenedos commented Nov 12, 2019 via email

@seertenedos
Copy link
Author

To really take advantage of this i would need to use docker healthchecks vs your WaitForTcp etc right? I just realised docker compose atleast supports waiting for health check so mixing that with the events could be a good way to monitor and act on things.

@mariotoffia mariotoffia changed the title Inter-container dependancy, health checks and WaitFor Docker Daemon Event Reception Support Mar 25, 2021
@mariotoffia
Copy link
Owner

I'm closing this now since the event reception has been implemented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement help wanted under-development Denotes that a issue is under development but not yet released.
Projects
None yet
Development

No branches or pull requests

2 participants