I have an application where one goroutine will eventually compute a value and at that point any number of routines waiting for that value need to continue execution. This a one-to-many communication problem so I struggled with channels and condition variables by keeping track of how many routines were waiting. Moreover, I wanted the broadcast to be non-blocking and future waits to return immediately since the value is known.
I ended up with the following implementation where closing the channel effectively broadcasts the group, since the write happens before any of the reads there should not be any races. Although works great so far seems a bit hackish to me. Is there a more idiomatic yet simple solution to this problem?
type BroadcastGroup struct {
ch chan interface{}
msg interface{}
}
func (bg *BroadcastGroup) Broadcast(msg interface{}) {
bg.msg = msg
close(bg.ch)
}
func (bg *BroadcastGroup) Wait() interface{} {
<-bg.ch
return bg.msg
}
func NewBroadcastGroup() *BroadcastGroup {
bg := &BroadcastGroup{}
bg.ch = make(chan interface{}, 0)
return bg
}