Skip to content

Commit

Permalink
avoid fancy strategies when balancing a FixedSubscriber with a single…
Browse files Browse the repository at this point in the history
… host
  • Loading branch information
kpacha committed Apr 13, 2018
1 parent 297e0c8 commit ffd90a4
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 31 deletions.
10 changes: 10 additions & 0 deletions sd/loadbalancing.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ var ErrNoHosts = errors.New("no hosts available")

// NewRoundRobinLB returns a new balancer using a round robin strategy
func NewRoundRobinLB(subscriber Subscriber) Balancer {
if s, ok := subscriber.(FixedSubscriber); ok && len(s) == 1 {
return nopBalancer(s[0])
}
return &roundRobinLB{
subscriber: subscriber,
counter: 0,
Expand All @@ -42,6 +45,9 @@ func (rr *roundRobinLB) Host() (string, error) {

// NewRandomLB returns a new balancer using a pseudo-random strategy
func NewRandomLB(subscriber Subscriber, seed int64) Balancer {
if s, ok := subscriber.(FixedSubscriber); ok && len(s) == 1 {
return nopBalancer(s[0])
}
return &randomLB{
subscriber: subscriber,
rnd: rand.New(rand.NewSource(seed)),
Expand All @@ -64,3 +70,7 @@ func (r *randomLB) Host() (string, error) {
}
return hosts[r.rnd.Intn(len(hosts))], nil
}

type nopBalancer string

func (b nopBalancer) Host() (string, error) { return string(b), nil }
83 changes: 52 additions & 31 deletions sd/loadbalancing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,48 @@ package sd

import (
"errors"
"fmt"
"math"
"testing"

"github.com/devopsfaith/krakend/config"
)

func TestRoundRobinLB(t *testing.T) {
var (
endpoints = []string{"a", "b", "c"}
n = len(endpoints)
counts = make(map[string]int, n)
iterations = 100000 * n
want = iterations / n
)

for _, e := range endpoints {
counts[e] = 0
}

subscriber := FixedSubscriber(endpoints)
balancer := NewRoundRobinLB(subscriber)

for i := 0; i < iterations; i++ {
endpoint, err := balancer.Host()
if err != nil {
t.Fail()
}
expected := i % n
if v := endpoints[expected]; v != endpoint {
t.Errorf("%d: want %s, have %s", i, endpoints[expected], endpoint)
}
counts[endpoint]++
}

for i, have := range counts {
if have != want {
t.Errorf("%s: want %d, have %d", i, want, have)
}
for _, endpoints := range balancerTestsCases {
t.Run(fmt.Sprintf("%d hosts", len(endpoints)), func(t *testing.T) {
var (
n = len(endpoints)
counts = make(map[string]int, n)
iterations = 100000 * n
want = iterations / n
)

for _, e := range endpoints {
counts[e] = 0
}

subscriber := FixedSubscriber(endpoints)
balancer := NewRoundRobinLB(subscriber)

for i := 0; i < iterations; i++ {
endpoint, err := balancer.Host()
if err != nil {
t.Fail()
}
expected := i % n
if v := endpoints[expected]; v != endpoint {
t.Errorf("%d: want %s, have %s", i, endpoints[expected], endpoint)
}
counts[endpoint]++
}

for i, have := range counts {
if have != want {
t.Errorf("%s: want %d, have %d", i, want, have)
}
}
})
}
}

Expand Down Expand Up @@ -86,6 +90,23 @@ func TestRandomLB(t *testing.T) {
}
}

func TestRandomLB_single(t *testing.T) {
endpoints := []string{"a"}
iterations := 1000000
subscriber := FixedSubscriber(endpoints)
balancer := NewRandomLB(subscriber, int64(12345))

for i := 0; i < iterations; i++ {
endpoint, err := balancer.Host()
if err != nil {
t.Fail()
}
if endpoint != endpoints[0] {
t.Errorf("unexpected host %s", endpoint)
}
}
}

func TestRandomLB_noEndpoints(t *testing.T) {
subscriber := FixedSubscriberFactory(&config.Backend{})
balancer := NewRandomLB(subscriber, 1415926)
Expand Down

0 comments on commit ffd90a4

Please sign in to comment.