mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 15:58:37 +00:00
client-go events: support context.Background() as context
If, for whatever reason, the context was context.Background(), the additional goroutine was started and then got stuck forever because context.Background().Done() is a nil channel. Found when indirectly instantiating a broadcaster with such a context: found unexpected goroutines: [Goroutine 9106 in state chan receive (nil chan), with k8s.io/kubernetes/vendor/k8s.io/client-go/tools/record.NewBroadcaster.func1 on top of the stack: goroutine 9106 [chan receive (nil chan)]: k8s.io/kubernetes/vendor/k8s.io/client-go/tools/record.NewBroadcaster.func1() /home/prow/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/vendor/k8s.io/client-go/tools/record/event.go:206 +0x2c created by k8s.io/kubernetes/vendor/k8s.io/client-go/tools/record.NewBroadcaster in goroutine 8957 /home/prow/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/vendor/k8s.io/client-go/tools/record/event.go:205 +0x1a5 This can be fixed by checking for a nil channel. Another problem also gets addressed: if Shutdown was called without canceling the context, the goroutine also didn't stop. Now it waits for the cancelation context and thus terminates in both cases.
This commit is contained in:
parent
55f2bc1043
commit
eed6e29a5b
@ -198,16 +198,29 @@ func NewBroadcaster(opts ...BroadcasterOption) EventBroadcaster {
|
||||
ctx := c.Context
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
} else {
|
||||
}
|
||||
// The are two scenarios where it makes no sense to wait for context cancelation:
|
||||
// - The context was nil.
|
||||
// - The context was context.Background() to begin with.
|
||||
//
|
||||
// Both cases get checked here.
|
||||
haveCtxCancelation := ctx.Done() == nil
|
||||
|
||||
eventBroadcaster.cancelationCtx, eventBroadcaster.cancel = context.WithCancel(ctx)
|
||||
|
||||
if haveCtxCancelation {
|
||||
// Calling Shutdown is not required when a context was provided:
|
||||
// when the context is canceled, this goroutine will shut down
|
||||
// the broadcaster.
|
||||
//
|
||||
// If Shutdown is called first, then this goroutine will
|
||||
// also stop.
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
<-eventBroadcaster.cancelationCtx.Done()
|
||||
eventBroadcaster.Broadcaster.Shutdown()
|
||||
}()
|
||||
}
|
||||
eventBroadcaster.cancelationCtx, eventBroadcaster.cancel = context.WithCancel(ctx)
|
||||
|
||||
return eventBroadcaster
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user