We're doing object copy on String call, but it makes race detector
angry: copy of sync.Once and changing its state at the same time. Also,
it fixes three vet warnings about passing lock by value.
Signed-off-by: Alexander Morozov <lk4d4math@gmail.com>
Let's try this once more...
Use a map instead of the same object type so that the String method
doesn't infinitely recurse.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Some log messages add an events.sink field whose value is the actual
sink object. Trying to log this can cause a data race, because some
sinks contain a sync.Once field:
WARNING: DATA RACE
Read at 0x00c42004beb0 by goroutine 75:
reflect.Value.Int()
/usr/local/go/src/reflect/value.go:886 +0x192
fmt.(*pp).printValue()
/usr/local/go/src/fmt/print.go:703 +0x39f6
fmt.(*pp).printValue()
/usr/local/go/src/fmt/print.go:764 +0x2d45
fmt.(*pp).printValue()
/usr/local/go/src/fmt/print.go:764 +0x2d45
fmt.(*pp).printValue()
/usr/local/go/src/fmt/print.go:764 +0x2d45
fmt.(*pp).printValue()
/usr/local/go/src/fmt/print.go:835 +0x2448
fmt.(*pp).printArg()
/usr/local/go/src/fmt/print.go:668 +0x1a3
fmt.(*pp).doPrint()
/usr/local/go/src/fmt/print.go:1113 +0xe3
fmt.Fprint()
/usr/local/go/src/fmt/print.go:215 +0x69
github.com/docker/swarmkit/vendor/github.com/Sirupsen/logrus.(*TextFormatter).appendKeyValue()
/home/ubuntu/.go_workspace/src/github.com/docker/swarmkit/vendor/github.com/Sirupsen/logrus/text_formatter.go:157
+0x134
github.com/docker/swarmkit/vendor/github.com/Sirupsen/logrus.(*TextFormatter).Format()
/home/ubuntu/.go_workspace/src/github.com/docker/swarmkit/vendor/github.com/Sirupsen/logrus/text_formatter.go:91
+0x6e6
github.com/docker/swarmkit/vendor/github.com/Sirupsen/logrus.(*Entry).Reader()
/home/ubuntu/.go_workspace/src/github.com/docker/swarmkit/vendor/github.com/Sirupsen/logrus/entry.go:44
+0x73
github.com/docker/swarmkit/vendor/github.com/Sirupsen/logrus.Entry.log()
/home/ubuntu/.go_workspace/src/github.com/docker/swarmkit/vendor/github.com/Sirupsen/logrus/entry.go:94
+0x1f6
github.com/docker/swarmkit/vendor/github.com/Sirupsen/logrus.(*Entry).Debug()
/home/ubuntu/.go_workspace/src/github.com/docker/swarmkit/vendor/github.com/Sirupsen/logrus/entry.go:119
+0x106
github.com/docker/swarmkit/vendor/github.com/docker/go-events.(*Queue).run()
/home/ubuntu/.go_workspace/src/github.com/docker/swarmkit/vendor/github.com/docker/go-events/queue.go:85
+0x2eb
Previous write at 0x00c42004beb0 by goroutine 67:
sync/atomic.AddInt32()
/usr/local/go/src/runtime/race_amd64.s:269 +0xb
sync.(*Mutex).Unlock()
/usr/local/go/src/sync/mutex.go:109 +0x54
sync.(*Once).Do()
/usr/local/go/src/sync/once.go:46 +0xa6
github.com/docker/swarmkit/vendor/github.com/docker/go-events.(*Channel).Close()
/home/ubuntu/.go_workspace/src/github.com/docker/swarmkit/vendor/github.com/docker/go-events/channel.go:45
+0x79
github.com/docker/swarmkit/manager/state/watch.(*Queue).CallbackWatch.func1()
/home/ubuntu/.go_workspace/src/github.com/docker/swarmkit/manager/state/watch/watch.go:48
+0x9d
github.com/docker/swarmkit/manager/state/watch.(*Queue).CallbackWatch.func2()
/home/ubuntu/.go_workspace/src/github.com/docker/swarmkit/manager/state/watch/watch.go:62
+0x126
github.com/docker/swarmkit/ca.(*Server).Run()
/home/ubuntu/.go_workspace/src/github.com/docker/swarmkit/ca/server.go:380
+0xb25
To avoid the data race, add String methods to objects that aren't safe
to serialize directly. These serialize a copy that excludes the
sync.Once.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
In a project where I use go-events, quite a few unit tests and
benchmarks read from a queue until they find what they're looking for,
and then stop reading. There may be more events published to the queue
afterwards, but there's no non-racy way to consume all of them and still
have the test terminate. Thus, these tests and benchmarks tend to log
many `WARN[0004] eventqueue: dropped event` messages.
Change this to the debug log level, so applications and unit tests which
use go-events are not forced to always consume all events to suppress
these messages.
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
To complement circuit breaker, we now have an exponential backoff retry
strategy. The common increasing bound strategy is implemented.
A small bug was exposed in the implementation that blocked the retry
forever if the strategy did not probe. Now, we simply wait for the retry
and proceed. This may change behavior in the breaker case, but is more
correct.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
After some analysis of stdlib, we found that time.After is sufficient to
avoid leaking a goroutine. This is because the send on the time channel
is actaully non-blocking.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
The docker/distribution/notifications package has been groomed for
general use. It now provides a tool for dispatching and routing of
events.
Signed-off-by: Stephen J Day <stephen.day@docker.com>