Merge pull request #7256 from thaJeztah/bump_go_events

vendor: github.com/docker/go-events v0.1.0
This commit is contained in:
Paweł Gronowski
2026-08-28 21:50:23 +02:00
committed by GitHub
12 changed files with 68 additions and 96 deletions
+1 -1
View File
@@ -77,7 +77,7 @@ require (
github.com/clipperhouse/uax29/v2 v2.2.0 // indirect
github.com/containerd/errdefs/pkg v0.3.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
github.com/docker/go-events v0.0.0-20260608200158-dbf6103125a4 // indirect
github.com/docker/go-events v0.1.0 // indirect
github.com/docker/go-metrics v0.1.0 // indirect
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect
github.com/felixge/httpsnoop v1.1.0 // indirect
+2 -2
View File
@@ -39,8 +39,8 @@ github.com/docker/docker-credential-helpers v0.9.9 h1:BkydjIgZ46JnDbqyM2p2fc63KM
github.com/docker/docker-credential-helpers v0.9.9/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c=
github.com/docker/go-connections v0.8.1 h1:JibmG5hULs5qXSr/cp/w3Pw5fZuStt4MOHMUExb29/M=
github.com/docker/go-connections v0.8.1/go.mod h1:no1qkHdjq7kLMGUXYAduOhYPSJxxvgWBh7ogVvptn3Q=
github.com/docker/go-events v0.0.0-20260608200158-dbf6103125a4 h1:Bj+mzWc7MJqqD0UzTaPmwszW3ttOVjSFi84ZU5l+2I0=
github.com/docker/go-events v0.0.0-20260608200158-dbf6103125a4/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
github.com/docker/go-events v0.1.0 h1:J8VX4H7Ta8mmBhv/K/24x1kosKOrEEnYmGjcdFHTOW0=
github.com/docker/go-events v0.1.0/go.mod h1:jwVwMgySJX4PiukIIRrind1wPGU8QhPa8aTEPkreUj4=
github.com/docker/go-metrics v0.1.0 h1:r76KPNpstz+IvQKSWpYegSkkyzex0V3A1ZGVx6bhGlY=
github.com/docker/go-metrics v0.1.0/go.mod h1:PciI3sONtB051kXALN1JoIlpcu54E1FuPh+4DuqEzyw=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
+2 -3
View File
@@ -1,8 +1,7 @@
# Docker Events Package
[![GoDoc](https://godoc.org/github.com/docker/go-events?status.svg)](https://godoc.org/github.com/docker/go-events)
[![ci](https://github.com/docker/go-events/actions/workflows/ci.yml/badge.svg)](https://github.com/docker/go-events/actions/workflows/ci.yml)
[![Go Report Card](https://goreportcard.com/badge/github.com/docker/go-events)](https://goreportcard.com/report/github.com/docker/go-events)
[![Go Reference](https://pkg.go.dev/badge/github.com/docker/go-events.svg)](https://pkg.go.dev/github.com/docker/go-events)
[![Build Status](https://github.com/docker/go-events/actions/workflows/ci.yml/badge.svg)](https://github.com/docker/go-events/actions/workflows/ci.yml)
The Docker `events` package implements a composable event distribution package
for Go.
+21 -32
View File
@@ -2,6 +2,7 @@ package events
import (
"fmt"
"slices"
"sync"
"github.com/sirupsen/logrus"
@@ -105,55 +106,46 @@ func (b *Broadcaster) Close() error {
// Close is called, this goroutine will exit.
func (b *Broadcaster) run() {
defer close(b.closed)
remove := func(target Sink) {
for i, sink := range b.sinks {
if sink == target {
b.sinks = append(b.sinks[:i], b.sinks[i+1:]...)
break
}
}
}
for {
select {
case event := <-b.events:
for _, sink := range b.sinks {
for i := 0; i < len(b.sinks); {
sink := b.sinks[i]
if err := sink.Write(event); err != nil {
if err == ErrSinkClosed {
// remove closed sinks
remove(sink)
b.sinks = slices.Delete(b.sinks, i, i+1)
continue
}
logrus.WithField("event", event).WithField("events.sink", sink).WithError(err).
Errorf("broadcaster: dropping event")
logrus.WithFields(logrus.Fields{
"error": err,
"event": event,
"events.sink": sink,
}).Error("broadcaster: dropping event")
}
i++
}
case request := <-b.adds:
// while we have to iterate for add/remove, common iteration for
// send is faster against slice.
var found bool
for _, sink := range b.sinks {
if request.sink == sink {
found = true
break
}
}
if !found {
// b.sinks[request.sink] = struct{}{}
if !slices.Contains(b.sinks, request.sink) {
b.sinks = append(b.sinks, request.sink)
}
// b.sinks[request.sink] = struct{}{}
request.response <- nil
case request := <-b.removes:
remove(request.sink)
if i := slices.Index(b.sinks, request.sink); i >= 0 {
b.sinks = slices.Delete(b.sinks, i, i+1)
}
request.response <- nil
case <-b.shutdown:
// close all the underlying sinks
for _, sink := range b.sinks {
if err := sink.Close(); err != nil && err != ErrSinkClosed {
logrus.WithField("events.sink", sink).WithError(err).
Errorf("broadcaster: closing sink failed")
logrus.WithFields(logrus.Fields{
"error": err,
"events.sink": sink,
}).Error("broadcaster: closing sink failed")
}
}
return
@@ -164,8 +156,7 @@ func (b *Broadcaster) run() {
func (b *Broadcaster) String() string {
// Serialize copy of this broadcaster without the sync.Once, to avoid
// a data race.
b2 := map[string]interface{}{
return fmt.Sprint(map[string]any{
"sinks": b.sinks,
"events": b.events,
"adds": b.adds,
@@ -173,7 +164,5 @@ func (b *Broadcaster) String() string {
"shutdown": b.shutdown,
"closed": b.closed,
}
return fmt.Sprint(b2)
})
}
+9 -5
View File
@@ -34,10 +34,15 @@ func (ch *Channel) Done() chan struct{} {
// the listener.
func (ch *Channel) Write(event Event) error {
select {
case ch.C <- event:
return nil
case <-ch.closed:
return ErrSinkClosed
default:
select {
case <-ch.closed:
return ErrSinkClosed
case ch.C <- event:
return nil
}
}
}
@@ -53,9 +58,8 @@ func (ch *Channel) Close() error {
func (ch *Channel) String() string {
// Serialize a copy of the Channel that doesn't contain the sync.Once,
// to avoid a data race.
ch2 := map[string]interface{}{
return fmt.Sprint(map[string]any{
"C": ch.C,
"closed": ch.closed,
}
return fmt.Sprint(ch2)
})
}
+1 -1
View File
@@ -1,7 +1,7 @@
package events
// Event marks items that can be sent as events.
type Event interface{}
type Event any
// Sink accepts and sends events.
type Sink interface {
+13 -8
View File
@@ -13,22 +13,27 @@ func (fn MatcherFunc) Match(event Event) bool {
return fn(event)
}
// Filter provides an event sink that sends only events that are accepted by a
// Matcher. No methods on filter are goroutine safe.
type Filter struct {
// Filter is the concrete implementation returned by [NewFilter].
//
// Deprecated: Filter should not be constructed directly. Use [NewFilter] instead.
type Filter = filter
type filter struct {
dst Sink
matcher Matcher
closed bool
}
// NewFilter returns a new filter that will send to events to dst that return
// true for Matcher.
// NewFilter returns a new event sink that forwards only events accepted by
// matcher to dst.
//
// The returned Sink's methods are not safe for concurrent use.
func NewFilter(dst Sink, matcher Matcher) Sink {
return &Filter{dst: dst, matcher: matcher}
return &filter{dst: dst, matcher: matcher}
}
// Write an event to the filter.
func (f *Filter) Write(event Event) error {
func (f *filter) Write(event Event) error {
if f.closed {
return ErrSinkClosed
}
@@ -41,7 +46,7 @@ func (f *Filter) Write(event Event) error {
}
// Close the filter and allow no more events to pass through.
func (f *Filter) Close() error {
func (f *filter) Close() error {
// TODO(stevvooe): Not all sinks should have Close.
if f.closed {
return nil
+1
View File
@@ -103,6 +103,7 @@ func (eq *Queue) next() Event {
eq.cond.Wait()
}
// Len is non-zero while holding eq.mu, so Front cannot be nil.
front := eq.events.Front()
block := front.Value.(Event)
eq.events.Remove(front)
+16 -21
View File
@@ -2,7 +2,7 @@ package events
import (
"fmt"
"math/rand"
"math/rand/v2"
"sync"
"sync/atomic"
"time"
@@ -26,13 +26,11 @@ type RetryingSink struct {
// off on failure. Parameters threshold and backoff adjust the behavior of the
// circuit breaker.
func NewRetryingSink(sink Sink, strategy RetryStrategy) *RetryingSink {
rs := &RetryingSink{
return &RetryingSink{
sink: sink,
strategy: strategy,
closed: make(chan struct{}),
}
return rs
}
// Write attempts to flush the events to the downstream sink until it succeeds
@@ -66,14 +64,12 @@ retry:
return err
}
logger := logger.WithError(err) // shadow!!
if rs.strategy.Failure(event, err) {
logger.Errorf("retryingsink: dropped event")
logger.WithError(err).Error("retryingsink: dropped event")
return nil
}
logger.Errorf("retryingsink: error writing event, retrying")
logger.WithError(err).Error("retryingsink: error writing event, retrying")
goto retry
}
@@ -93,7 +89,7 @@ func (rs *RetryingSink) Close() error {
func (rs *RetryingSink) String() string {
// Serialize a copy of the RetryingSink without the sync.Once, to avoid
// a data race.
rs2 := map[string]interface{}{
rs2 := map[string]any{
"sink": rs.sink,
"strategy": rs.strategy,
"closed": rs.closed,
@@ -201,7 +197,7 @@ type ExponentialBackoffConfig struct {
// ExponentialBackoff implements random backoff with exponentially increasing
// bounds as the number consecutive failures increase.
type ExponentialBackoff struct {
failures uint64 // consecutive failure counter (needs to be 64-bit aligned)
failures atomic.Uint64 // consecutive failure counter (needs to be 64-bit aligned)
config ExponentialBackoffConfig
}
@@ -215,17 +211,17 @@ func NewExponentialBackoff(config ExponentialBackoffConfig) *ExponentialBackoff
// Proceed returns the next randomly bound exponential backoff time.
func (b *ExponentialBackoff) Proceed(event Event) time.Duration {
return b.backoff(atomic.LoadUint64(&b.failures))
return b.backoff(b.failures.Load())
}
// Success resets the failures counter.
func (b *ExponentialBackoff) Success(event Event) {
atomic.StoreUint64(&b.failures, 0)
b.failures.Store(0)
}
// Failure increments the failure counter.
func (b *ExponentialBackoff) Failure(event Event, err error) bool {
atomic.AddUint64(&b.failures, 1)
b.failures.Add(1)
return false
}
@@ -242,17 +238,16 @@ func (b *ExponentialBackoff) backoff(failures uint64) time.Duration {
factor = DefaultExponentialBackoffConfig.Factor
}
backoff := b.config.Base + factor*time.Duration(1<<(failures-1))
max := b.config.Max
if max <= 0 {
max = DefaultExponentialBackoffConfig.Max
maxBackoff := b.config.Max
if maxBackoff <= 0 {
maxBackoff = DefaultExponentialBackoffConfig.Max
}
if backoff > max || backoff < 0 {
backoff = max
backoff := b.config.Base + factor*time.Duration(1<<(failures-1))
if backoff > maxBackoff || backoff < 0 {
backoff = maxBackoff
}
// Choose a uniformly distributed value from [0, backoff).
return time.Duration(rand.Int63n(int64(backoff)))
return rand.N(backoff)
}
-5
View File
@@ -1,5 +0,0 @@
module github.com/docker/go-events
go 1.13
require github.com/sirupsen/logrus v1.9.3
-16
View File
@@ -1,16 +0,0 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+2 -2
View File
@@ -77,8 +77,8 @@ github.com/docker/docker-credential-helpers/credentials
github.com/docker/go-connections/nat
github.com/docker/go-connections/sockets
github.com/docker/go-connections/tlsconfig
# github.com/docker/go-events v0.0.0-20260608200158-dbf6103125a4
## explicit
# github.com/docker/go-events v0.1.0
## explicit; go 1.24
github.com/docker/go-events
# github.com/docker/go-metrics v0.1.0
## explicit; go 1.21