Skip to content

Instantly share code, notes, and snippets.

@17twenty
Last active July 20, 2022 12:46
Show Gist options
  • Save 17twenty/ada7dd263e9a957126571fa56c8d280f to your computer and use it in GitHub Desktop.
Save 17twenty/ada7dd263e9a957126571fa56c8d280f to your computer and use it in GitHub Desktop.
Using reflect.SelectCase - an example
package main
import (
"log"
"reflect"
"time"
)
func main() {
c1 := make(chan int)
c2 := make(chan string)
c3 := make(chan bool)
go func() {
for i := 0; i < 5; i++ {
time.Sleep(50 * time.Millisecond)
c1 <- i
log.Println("c2 <- ", <-c2)
c3 <- true
}
}()
cases := []reflect.SelectCase{
{
Dir: reflect.SelectRecv,
Chan: reflect.ValueOf(c1),
},
{
Dir: reflect.SelectSend,
Chan: reflect.ValueOf(c2),
Send: reflect.ValueOf("Hello"),
},
{
Dir: reflect.SelectRecv,
Chan: reflect.ValueOf(c3),
},
{
Dir: reflect.SelectDefault,
},
}
for i := 0; i < 10; i++ {
time.Sleep(1 * time.Second)
switch index, value, recvOK := reflect.Select(cases); index {
case 0:
// c1 was selected, recv is the value received
// we get recvOK whether we need it or not
log.Println("case 0:", value, recvOK)
case 1:
// c2 was selected, therefore "hello" was sent
// recv and recvOK are garbage
log.Println("case 1: There was a read on the channel ready")
case 2:
// c3 was selected, value is good if recvOK == true
// recvOK is false if c3 is closed
log.Println("case 2:", value, recvOK)
case 3:
// default case
// recv and recvOK are useless here
log.Println("case 3: reflect.SelectDefault,")
}
}
}
// Run multiplexer until it receives an EOF on the control channel.
func (mux *Multiplexer) Run() {
for {
index, value, recv := reflect.Select(mux.selectCases)
EOF := !recv
// note that the control channel is always at index 0
if index == 0 {
if EOF {
return
}
muxInput, _ := value.Interface().(*muxInputSource)
mux.selectCases = append(mux.selectCases, reflect.SelectCase{
Dir: reflect.SelectRecv,
Chan: reflect.ValueOf(muxInput.collection),
Send: reflect.Value{},
})
} else {
if EOF {
mux.writeEOF()
mux.selectCases = append(mux.selectCases[:index], mux.selectCases[index+1:]...)
} else {
document, _ := value.Interface().([]byte)
mux.writeDocument(document)[]
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment