kubernetes/apimachinery

Receive only close channel.

Skarlso opened this issue · 1 comments

Hello. I'm seeking some answers.

There is this code in wait.go:

// ContextForChannel provides a context that will be treated as cancelled
// when the provided parentCh is closed. The implementation returns
// context.Canceled for Err() if and only if the parentCh is closed.
func ContextForChannel(parentCh <-chan struct{}) context.Context {
	return channelContext{stopCh: parentCh}
}

var _ context.Context = channelContext{}

// channelContext will behave as if the context were cancelled when stopCh is
// closed.
type channelContext struct {
	stopCh <-chan struct{}
}

func (c channelContext) Done() <-chan struct{} { return c.stopCh }
func (c channelContext) Err() error {
	select {
	case <-c.stopCh:
		return context.Canceled
	default:
		return nil
	}
}

This will never work because the parent channel is declared as receive only channel.

You can't close a receive only channel as closing is a send operation. There are other places where the close channel is declared as receive only. What's the rational there?

Nevermind. The passed in channel is bidirectional and IT can be closed:

type namedChannelWrapper struct {
	name string
	once sync.Once
	ch   chan struct{}
}

func (e *namedChannelWrapper) Signal() {
	e.once.Do(func() {
		close(e.ch)
	})
}

func (e *namedChannelWrapper) Signaled() <-chan struct{} {
	return e.ch
}

func (e *namedChannelWrapper) Name() string {
	return e.name
}