fix: allocates new objects each time (#1802)

pull/1808/head
Tony Chen 3 years ago committed by GitHub
parent 18315303f0
commit 34d0cccefd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 20
      selector/p2c/p2c.go

@ -3,6 +3,7 @@ package p2c
import ( import (
"context" "context"
"math/rand" "math/rand"
"sync"
"sync/atomic" "sync/atomic"
"time" "time"
@ -40,15 +41,17 @@ func New(opts ...Option) selector.Selector {
// Balancer is p2c selector. // Balancer is p2c selector.
type Balancer struct { type Balancer struct {
r *rand.Rand mu sync.Mutex
lk int64 r *rand.Rand
picked int64
} }
// choose two distinct nodes. // choose two distinct nodes.
func (s *Balancer) prePick(nodes []selector.WeightedNode) (nodeA selector.WeightedNode, nodeB selector.WeightedNode) { func (s *Balancer) prePick(nodes []selector.WeightedNode) (nodeA selector.WeightedNode, nodeB selector.WeightedNode) {
source := rand.NewSource(time.Now().UnixNano()) s.mu.Lock()
a := rand.New(source).Intn(len(nodes)) a := s.r.Intn(len(nodes))
b := rand.New(source).Intn(len(nodes) - 1) b := s.r.Intn(len(nodes) - 1)
s.mu.Unlock()
if b >= a { if b >= a {
b = b + 1 b = b + 1
} }
@ -60,7 +63,8 @@ func (s *Balancer) prePick(nodes []selector.WeightedNode) (nodeA selector.Weight
func (s *Balancer) Pick(ctx context.Context, nodes []selector.WeightedNode) (selector.WeightedNode, selector.DoneFunc, error) { func (s *Balancer) Pick(ctx context.Context, nodes []selector.WeightedNode) (selector.WeightedNode, selector.DoneFunc, error) {
if len(nodes) == 0 { if len(nodes) == 0 {
return nil, nil, selector.ErrNoAvailable return nil, nil, selector.ErrNoAvailable
} else if len(nodes) == 1 { }
if len(nodes) == 1 {
done := nodes[0].Pick() done := nodes[0].Pick()
return nodes[0], done, nil return nodes[0], done, nil
} }
@ -76,9 +80,9 @@ func (s *Balancer) Pick(ctx context.Context, nodes []selector.WeightedNode) (sel
// If the failed node has never been selected once during forceGap, it is forced to be selected once // If the failed node has never been selected once during forceGap, it is forced to be selected once
// Take advantage of forced opportunities to trigger updates of success rate and delay // Take advantage of forced opportunities to trigger updates of success rate and delay
if upc.PickElapsed() > forcePick && atomic.CompareAndSwapInt64(&s.lk, 0, 1) { if upc.PickElapsed() > forcePick && atomic.CompareAndSwapInt64(&s.picked, 0, 1) {
pc = upc pc = upc
atomic.StoreInt64(&s.lk, 0) atomic.StoreInt64(&s.picked, 0)
} }
done := pc.Pick() done := pc.Pick()
return pc, done, nil return pc, done, nil

Loading…
Cancel
Save