From b62df94b39dcbe6c7eb8d7e95a35b937233f97ea Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Wed, 10 Jul 2019 18:38:26 +0200 Subject: [PATCH] Fix race condition on error returned after context cancellation (#12743) After #11981 docker client watching event uses the context provided by the metricset wrapper. This produces a race condition on error reporting: the errors channel will receive a context cancelled error when the context is done, so both paths can be chosen by the select. If the errors one is chosen, an error will be reported and a reconnect will be attempted, that will fail. Alternativelly we could have created another context and cancel it after the reporter is done, in a similar fashion to what was done before #11981, but then we would be breaking the chain of derived contexts. (cherry picked from commit d36878a5ce4fb8980c582d3a7b8ee75ece895209) --- metricbeat/module/docker/event/event.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/metricbeat/module/docker/event/event.go b/metricbeat/module/docker/event/event.go index 6426ffeb961..f81168b9de9 100644 --- a/metricbeat/module/docker/event/event.go +++ b/metricbeat/module/docker/event/event.go @@ -94,13 +94,21 @@ func (m *MetricSet) Run(ctx context.Context, reporter mb.ReporterV2) { m.reportEvent(reporter, event) case err := <-errors: + // An error can be received on context cancellation, don't reconnect + // if context is done. + select { + case <-ctx.Done(): + m.logger.Debug("docker", "Event watcher stopped") + return + default: + } // Restart watch call - m.logger.Error("Error watching for docker events: %v", err) + m.logger.Errorf("Error watching for docker events: %v", err) time.Sleep(1 * time.Second) break WATCH case <-ctx.Done(): - m.logger.Debug("docker", "event watcher stopped") + m.logger.Debug("docker", "Event watcher stopped") return } }