Sep 13, 2019

[Go] select through slice of channels from reflect.Select

e.g https://play.golang.org/p/Ul-e3DoVv5K
package main

import (
 "context"
 "fmt"
 "math/rand"
 "reflect"
 "time"
)

func main() {
 const numberOfTest = 10
 soc := make([]reflect.SelectCase, numberOfTest)
 channels := make([]chan int, numberOfTest)

 for idx := range channels {
  channels[idx] = make(chan int, 1)
 }

 for i := range soc {
  soc[i] = reflect.SelectCase{
   Dir:  reflect.SelectRecv,
   Chan: reflect.ValueOf(channels[i]),
  }
 }

 ctx, cancel := context.WithCancel(context.Background())

 go func() {
  send := make(chan struct {
   int
   reflect.Value
   bool
  }, 1)

  receive := send

  go func() {
   for {
    // block call, could use a circuit breaker,
    // e.g https://github.com/sony/gobreaker
    idx, val, ok := reflect.Select(soc)

    send <- struct {
     int
     reflect.Value
     bool
    }{idx, val, ok}
   }
  }()

  for {
   select {
   case <-ctx.Done():
    fmt.Println("bye~")
    return
   case payload := <-receive:
    fmt.Printf("idx: %d, value: %v, bool: %t\n",
     payload.int,
     payload.Value,
     payload.bool)
   }
  }
 }()

 go func() {
  for {
   for idx := range channels {
    channels[idx] <- rand.Intn(100)
   }

   time.Sleep(3 * time.Second)
  }

 }()

 time.Sleep(10 * time.Second)
 cancel()
 time.Sleep(3 * time.Second)
}

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.