Skip to content

Commit

Permalink
add ut, improve implement
Browse files Browse the repository at this point in the history
 Signed-off-by: liuqing6767  <[email protected]>
  • Loading branch information
liuqing6767 committed Sep 15, 2024
1 parent 8d894b0 commit 777a629
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 32 deletions.
36 changes: 9 additions & 27 deletions bfe_balance/bal_slb/bal_rr.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,12 @@ import (
"math/rand"
"sort"
"sync"
)

import (
"github.com/baidu/go-lib/log"
"github.com/spaolacci/murmur3"
)

import (
"github.com/bfenetworks/bfe/bfe_balance/backend"
"github.com/bfenetworks/bfe/bfe_config/bfe_cluster_conf/cluster_table_conf"
"github.com/bfenetworks/bfe/bfe_debug"
"github.com/spaolacci/murmur3"
)

// implementation versions of weighted round-robin algorithm
Expand Down Expand Up @@ -322,47 +317,34 @@ func (brr *BalanceRR) leastConnsSimpleBalance() (*backend.BfeBackend, error) {
}

func leastConnsBalance(backs BackendList) (BackendList, error) {
var best *BackendRR
candidates := make(BackendList, 0, len(backs))

// select available candidates
singleBackend := true
for _, backendRR := range backs {
if !backendRR.backend.Avail() || backendRR.weight <= 0 {
continue
}

if best == nil {
best = backendRR
singleBackend = true
if len(candidates) == 0 {
candidates = append(candidates, backendRR) // init
continue
}

// compare backends
ret := compLCWeight(best, backendRR)
ret := compLCWeight(candidates[0], backendRR)
if ret > 0 {
best = backendRR
singleBackend = true
candidates = candidates[0:0] // reset
candidates = append(candidates, backendRR)
} else if ret == 0 {
singleBackend = false
if len(candidates) > 0 {
candidates = append(candidates, backendRR)
} else {
candidates = append(candidates, best, backendRR)
}

// more than one backend have same connections/weight
candidates = append(candidates, backendRR)
}
}

if best == nil {
if len(candidates) == 0 {
return nil, fmt.Errorf("rr_bal:all backend is down")
}

// single backend, return directly
if singleBackend {
return BackendList{best}, nil
}
// more than one backend have same connections/weight,
// return all the candidates
return candidates, nil
}
Expand Down
81 changes: 76 additions & 5 deletions bfe_balance/bal_slb/bal_rr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ import (
"math/rand"
"reflect"
"testing"
)

import (
"github.com/bfenetworks/bfe/bfe_balance/backend"
"github.com/bfenetworks/bfe/bfe_config/bfe_cluster_conf/cluster_table_conf"
"github.com/bfenetworks/bfe/bfe_util/json"
Expand Down Expand Up @@ -131,7 +129,7 @@ func processBalancLoopTwenty(t *testing.T, label string, algor int, key []byte,

func processSimpleBalance(t *testing.T, label string, algor int, key []byte, rr *BalanceRR, result []string) {
var l []string
loopCount := (300+200+100)+4
loopCount := (300 + 200 + 100) + 4

for i := 1; i < loopCount; i++ {
r, err := rr.Balance(algor, key)
Expand All @@ -156,7 +154,7 @@ func processSimpleBalance(t *testing.T, label string, algor int, key []byte, rr

func processSimpleBalance3(t *testing.T, label string, algor int, key []byte, rr *BalanceRR, result []string) {
var l []string
loopCount := (200+100)*3+4
loopCount := (200+100)*3 + 4

for i := 1; i < loopCount; i++ {
r, err := rr.Balance(algor, key)
Expand Down Expand Up @@ -218,7 +216,7 @@ func TestBalance(t *testing.T) {
rr.backends[0].backend.SetAvail(false)
// after scale up 100, the hash result changed
expectResult = []string{"b3", "b3", "b3", "b3", "b3", "b3", "b3", "b3", "b3"}
// expectResult = []string{"b2", "b2", "b2", "b2", "b2", "b2", "b2", "b2", "b2"}
// expectResult = []string{"b2", "b2", "b2", "b2", "b2", "b2", "b2", "b2", "b2"}
processBalance(t, "case 6", WrrSticky, []byte{1}, rr, expectResult)

// case 7, lcw balance
Expand Down Expand Up @@ -363,3 +361,76 @@ func TestSlowStart(t *testing.T) {
rr := prepareBalanceRR()
rr.SetSlowStart(30)
}

func Test_leastConnsBalance(t *testing.T) {
b0_0 := &BackendRR{backend: backend.NewBfeBackend(), weight: 0}
b0_1 := &BackendRR{backend: backend.NewBfeBackend(), weight: 0}

b1_1 := &BackendRR{backend: backend.NewBfeBackend(), weight: 1}

b2_1 := &BackendRR{backend: backend.NewBfeBackend(), weight: 2}
b2_2 := &BackendRR{backend: backend.NewBfeBackend(), weight: 2}
b2_3 := &BackendRR{backend: backend.NewBfeBackend(), weight: 2}

b3_1 := &BackendRR{backend: backend.NewBfeBackend(), weight: 3}
b3_3 := &BackendRR{backend: backend.NewBfeBackend(), weight: 3}

b0_0.backend.Name = "b0_0"
b0_1.backend.Name = "b0_1"
b1_1.backend.Name = "b1_1"
b2_1.backend.Name = "b2_1"
b2_2.backend.Name = "b2_2"
b2_3.backend.Name = "b2_3"
b3_1.backend.Name = "b3_1"
b3_3.backend.Name = "b3_3"

b0_1.backend.IncConnNum()
b1_1.backend.IncConnNum()
b2_1.backend.IncConnNum()

b2_2.backend.IncConnNum()
b2_2.backend.IncConnNum()

b2_3.backend.IncConnNum()
b2_3.backend.IncConnNum()
b2_3.backend.IncConnNum()

b3_1.backend.IncConnNum()

b3_3.backend.IncConnNum()
b3_3.backend.IncConnNum()
b3_3.backend.IncConnNum()

for _, cas := range []struct {
name string
backends BackendList
wantCandidates []string
wantErr bool
}{
{name: "all down", backends: BackendList{b0_0, b0_1}, wantCandidates: nil, wantErr: true},
{name: "all same", backends: BackendList{b1_1, b2_2, b3_3}, wantCandidates: []string{"b1_1", "b2_2", "b3_3"}, wantErr: false},
{name: "incr1", backends: BackendList{b2_1, b2_2, b2_3}, wantCandidates: []string{"b2_1"}, wantErr: false},
{name: "desc1", backends: BackendList{b2_3, b2_2, b2_1}, wantCandidates: []string{"b2_1"}, wantErr: false},
{name: "incr2", backends: BackendList{b3_1, b2_1, b1_1}, wantCandidates: []string{"b3_1"}, wantErr: false},
{name: "desc2", backends: BackendList{b1_1, b2_1, b3_1}, wantCandidates: []string{"b3_1"}, wantErr: false},
{name: "just one", backends: BackendList{b2_1}, wantCandidates: []string{"b2_1"}, wantErr: false},
} {
got, err := leastConnsBalance(cas.backends)

if !cas.wantErr && err != nil {
t.Errorf("%s: leastConnsBalance() error = %v", cas.name, err)
}
if cas.wantErr {
continue
}

gotList := []string{}
for _, one := range got {
gotList = append(gotList, one.backend.Name)
}

if !reflect.DeepEqual(gotList, cas.wantCandidates) {
t.Errorf("%s: want: %v, got: %v", cas.name, cas.wantCandidates, gotList)
}
}
}

0 comments on commit 777a629

Please sign in to comment.