There are two channels that will be used for signaling by closing them. How to make one channel from them that will be closed if at least one of them is closed. This code illustrates what I would like to do:
func MergeChans(c1 chan struct{}, c2 chan struct{}) chan struct{} {
c3 := make(chan struct{})
go func() {
select {
case <-c1: close(c3)
case <-c2: close(c3)
}
}()
return c3
}
Is it possible to achieve this without subroutine?
If you want to return the "merged" channel before it needs to be closed, no.
But this isn't a problem, the goroutine you launch inside will use 0 CPU resources. You shouldn't worry about that.
Once one of the channels is closed, the function will end and and thus the goroutine will terminate properly. You only have to make sure that at least one of the channels gets closed. If you can't guarantee this, the goroutine would never terminate and would never get garbage-collected. If you don't control the channels, you could pass a 3rd channel (or a context.Context
value) to provide a way of proper termination, e.g.:
func MergeChans(c1, c2, shutdown chan struct{}) chan struct{} {
c3 := make(chan struct{})
go func() {
select {
case <-c1:
close(c3)
case <-c2:
close(c3)
case <-shutdown:
}
}()
return c3
}
If you want to avoid the extra goroutine, then don't merge them (add 2 case
s where they need to be monitored).