roundrobin.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package balancer
  2. import (
  3. "context"
  4. "math/rand"
  5. "sync"
  6. "time"
  7. "google.golang.org/grpc/balancer"
  8. "google.golang.org/grpc/balancer/base"
  9. "google.golang.org/grpc/resolver"
  10. )
  11. const Name = "roundrobin"
  12. func init() {
  13. balancer.Register(newBuilder())
  14. }
  15. type roundRobinPickerBuilder struct {
  16. }
  17. func newBuilder() balancer.Builder {
  18. return base.NewBalancerBuilder(Name, new(roundRobinPickerBuilder))
  19. }
  20. func (b *roundRobinPickerBuilder) Build(readySCs map[resolver.Address]balancer.SubConn) balancer.Picker {
  21. rand.Seed(time.Now().UnixNano())
  22. picker := &roundRobinPicker{
  23. index: rand.Int(),
  24. }
  25. for addr, conn := range readySCs {
  26. picker.conns = append(picker.conns, &subConn{
  27. addr: addr,
  28. conn: conn,
  29. })
  30. }
  31. return picker
  32. }
  33. type roundRobinPicker struct {
  34. conns []*subConn
  35. index int
  36. lock sync.Mutex
  37. }
  38. func (p *roundRobinPicker) Pick(ctx context.Context, info balancer.PickInfo) (
  39. conn balancer.SubConn, done func(balancer.DoneInfo), err error) {
  40. p.lock.Lock()
  41. defer p.lock.Unlock()
  42. p.index = (p.index + 1) % len(p.conns)
  43. return p.conns[p.index].conn, func(info balancer.DoneInfo) {
  44. }, nil
  45. }
  46. type subConn struct {
  47. addr resolver.Address
  48. conn balancer.SubConn
  49. }