watchUntilDestroy waits for the container to be created, started, or unpaused, and then reset the idle timer. When the container is stopped, paused, or killed, the idle timer is stopped and the ContainerRunning flag is set to false. When the idle timer fires, the container is stopped according to
()
| 563 | // it exits only if the context is canceled, the container is destroyed, |
| 564 | // errors occurred on docker client, or route provider died (mainly caused by config reload). |
| 565 | func (w *Watcher) watchUntilDestroy() (returnCause error) { |
| 566 | p := w.provider.Load() |
| 567 | if p == nil { |
| 568 | return errors.New("provider not set") |
| 569 | } |
| 570 | defer p.Close() |
| 571 | eventCh, errCh := p.Watch(w.Task().Context()) |
| 572 | |
| 573 | for { |
| 574 | select { |
| 575 | case <-w.task.Context().Done(): |
| 576 | return w.task.FinishCause() |
| 577 | case err := <-errCh: |
| 578 | w.l.Err(err).Msg("watcher error") |
| 579 | case e := <-eventCh: |
| 580 | w.l.Debug().Stringer("action", e.Action).Msg("state changed") |
| 581 | switch e.Action { |
| 582 | case watcherEvents.ActionContainerDestroy: |
| 583 | return errCauseContainerDestroy |
| 584 | case watcherEvents.ActionForceReload: |
| 585 | continue |
| 586 | } |
| 587 | w.resetIdleTimer() |
| 588 | switch { |
| 589 | case e.Action.IsContainerStart(): // create / start / unpause |
| 590 | w.setStarting() |
| 591 | w.healthTicker.Reset(idleWakerCheckInterval) // start health checking |
| 592 | w.l.Info().Msg("awaken") |
| 593 | case e.Action.IsContainerStop(): // stop / kill / die |
| 594 | w.setNapping(idlewatcher.ContainerStatusStopped) |
| 595 | w.idleTicker.Stop() |
| 596 | w.healthTicker.Stop() // stop health checking |
| 597 | case e.Action.IsContainerPause(): // pause |
| 598 | w.setNapping(idlewatcher.ContainerStatusPaused) |
| 599 | w.idleTicker.Stop() |
| 600 | w.healthTicker.Stop() // stop health checking |
| 601 | default: |
| 602 | w.l.Debug().Stringer("action", e.Action).Msg("unexpected container action") |
| 603 | } |
| 604 | case <-w.healthTicker.C: |
| 605 | // Only check health if container is starting (not ready yet) |
| 606 | if w.running() && !w.ready() { |
| 607 | ready, err := w.checkUpdateState() |
| 608 | if err != nil { |
| 609 | // Health check failed with error, stop health checking |
| 610 | w.healthTicker.Stop() |
| 611 | continue |
| 612 | } |
| 613 | if ready { |
| 614 | // Container is now ready, notify waiting handlers |
| 615 | w.healthTicker.Stop() |
| 616 | w.resetIdleTimer() |
| 617 | } |
| 618 | // If not ready yet, keep checking on next tick |
| 619 | } |
| 620 | case <-w.idleTicker.C: |
| 621 | w.idleTicker.Stop() |
| 622 | if w.running() { |
no test coverage detected