Description
Proposal: when creating a channel, if the capacity passed to the make builtin function is negative, the channel will have unlimited capacity. Such channels will never block when sending and will always be ready for sending.
Rationale: channels are a natural way to implement queues. When processing streams of data, it is unknown how many data elements will be sent. In some cases, fixed length channels can lead to deadlocks. These deadlocks can be eliminated with unlimited capacity channels.
This is how I currently work around the limitation:
func NewQueue() (chan<- interface{}, <-chan interface{}) {
send := make(chan interface{}, 1)
receive := make(chan interface{}, 1)
go manageQueue(send, receive)
return send, receive
}
func manageQueue(send <-chan interface{}, receive chan<- interface{}) {
queue := list.New()
for {
if front := queue.Front(); front == nil {
if send == nil {
close(receive)
return
}
value, ok := <-send
if !ok {
close(receive)
return
}
queue.PushBack(data)
} else {
select {
case receive <- front.Value:
queue.Remove(front)
case value, ok := <-send:
if ok {
queue.PushBack(data)
} else {
send = nil
}
}
}
}
}
The disadvantage of this workaround is that it forces all the users to perform type casting, so you lose the compile-time type checking. If you want compile-time type checking you need to re-implement the above code over and over again for each queue type. Unlimited length channels would avoid the need for all that boilerplate.