Skip to content

Commit

Permalink
Implemented priority + weight balancing #204
Browse files Browse the repository at this point in the history
  • Loading branch information
illarion committed Jun 13, 2019
1 parent d61e5b9 commit ee6d535
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 8 deletions.
5 changes: 3 additions & 2 deletions config/gobetween.toml
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,9 @@ bind = "0.0.0.0:3000"
[servers.sample.discovery]
kind = "static"
static_list = [
"localhost:8000",
"localhost:8001"
"localhost:8000 weight=40 priority=1",
"localhost:8001 weight=60 priority=1",
"localhost:8002 weight=100 priority=0"
]

# ---------- udp example ----------- #
Expand Down
46 changes: 40 additions & 6 deletions src/balance/weight.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package balance

import (
"errors"
"fmt"
"math/rand"

"github.com/yyyar/gobetween/core"
Expand All @@ -19,26 +20,59 @@ import (
type WeightBalancer struct{}

/**
* Elect backend based on weight strategy
* Elect backend based on weight with priority strategy.
* See https://tools.ietf.org/html/rfc2782, Priority and Weight sections
*/
func (b *WeightBalancer) Elect(context core.Context, backends []*core.Backend) (*core.Backend, error) {

if len(backends) == 0 {
return nil, errors.New("Can't elect backend, Backends empty")
}

totalWeight := 0
if len(backends) == 1 {
return backends[0], nil
}

// according to RFC we should use backends with lowest priority
minPriority := backends[0].Priority
// group of backends with priority == minPriority
group := make([]*core.Backend, 0, len(backends))
// sum of weights in the group
groupSumWeight := 0

for _, backend := range backends {

if backend.Priority > minPriority {
continue
}

if backend.Priority < 0 {
return nil, fmt.Errorf("Invalid backend priority, shold not be less than 0: %v", backend.Priority)
}

if backend.Weight <= 0 {
return nil, errors.New("Invalid backend weight 0")
return nil, fmt.Errorf("Invalid backend weight, should not be less or equal to 0: %v", backend.Weight)
}

// got new lower priority, reset
if backend.Priority < minPriority {
minPriority = backend.Priority
group = make([]*core.Backend, 0, len(backends))
groupSumWeight = 0
}
totalWeight += backend.Weight

group = append(group, backend)
groupSumWeight += backend.Weight
}

r := rand.Intn(totalWeight)
if len(group) == 1 {
return group[0], nil
}

r := rand.Intn(groupSumWeight)
pos := 0

for _, backend := range backends {
for _, backend := range group {
pos += backend.Weight
if r >= pos {
continue
Expand Down

0 comments on commit ee6d535

Please sign in to comment.