// RegisterDockerEventListener registers function as event listener with docker. // laziness defines how many seconds to wait, after an event is received, until a refresh is triggered func RegisterDockerEventListener(client *docker.Client, function func(), wg *sync.WaitGroup, laziness int) { wg.Add(1) defer wg.Done() events := make(chan *docker.APIEvents) defer close(events) err := client.AddEventListener((chan<- *docker.APIEvents)(events)) if err != nil { log.Fatalf("Unable to add docker event listener: %s", err) } defer client.RemoveEventListener(events) log.Info("Listening to docker events...") for { event := <-events if event == nil { continue } if event.Status == "start" || event.Status == "stop" || event.Status == "die" { log.Debug("Received event %s for container %s", event.Status, event.ID[:12]) Refresh.Mu.Lock() if !Refresh.IsTriggered { log.Info("Triggering refresh in %d seconds", laziness) Refresh.timer = time.AfterFunc(time.Duration(laziness)*time.Second, function) Refresh.IsTriggered = true } Refresh.Mu.Unlock() } } }
func generateFromEvents(client *docker.Client, configs ConfigFile) { configs = configs.filterWatches() if len(configs.Config) == 0 { return } wg.Add(1) defer wg.Done() for { if client == nil { var err error endpoint, err := getEndpoint() if err != nil { log.Printf("Bad endpoint: %s", err) time.Sleep(10 * time.Second) continue } client, err = NewDockerClient(endpoint) if err != nil { log.Printf("Unable to connect to docker daemon: %s", err) time.Sleep(10 * time.Second) continue } generateFromContainers(client) } eventChan := make(chan *docker.APIEvents, 100) defer close(eventChan) watching := false for { if client == nil { break } err := client.Ping() if err != nil { log.Printf("Unable to ping docker daemon: %s", err) if watching { client.RemoveEventListener(eventChan) watching = false client = nil } time.Sleep(10 * time.Second) break } if !watching { err = client.AddEventListener(eventChan) if err != nil && err != docker.ErrListenerAlreadyExists { log.Printf("Error registering docker event listener: %s", err) time.Sleep(10 * time.Second) continue } watching = true log.Println("Watching docker events") } select { case event := <-eventChan: if event == nil { if watching { client.RemoveEventListener(eventChan) watching = false client = nil } break } if event.Status == "start" || event.Status == "stop" || event.Status == "die" { log.Printf("Received event %s for container %s", event.Status, event.ID[:12]) generateFromContainers(client) } case <-time.After(10 * time.Second): // check for docker liveness } } } }