reverseproxy: Allow 0 as weights for weighted_round_robin (#6681)
Some checks failed
Tests / test (./cmd/caddy/caddy, ~1.22.3, macos-14, 0, 1.22, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy, ~1.22.3, ubuntu-latest, 0, 1.22, linux) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy, ~1.23.0, macos-14, 0, 1.23, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy, ~1.23.0, ubuntu-latest, 0, 1.23, linux) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.22.3, windows-latest, True, 1.22, windows) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.23.0, windows-latest, True, 1.23, windows) (push) Has been cancelled
Tests / test (s390x on IBM Z) (push) Has been cancelled
Tests / goreleaser-check (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (ubuntu-latest, linux) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Lint / govulncheck (push) Has been cancelled
Cross-Build / build (~1.22.3, 1.22, aix) (push) Has been cancelled
Cross-Build / build (~1.22.3, 1.22, darwin) (push) Has been cancelled
Cross-Build / build (~1.22.3, 1.22, dragonfly) (push) Has been cancelled
Cross-Build / build (~1.22.3, 1.22, freebsd) (push) Has been cancelled
Cross-Build / build (~1.22.3, 1.22, illumos) (push) Has been cancelled
Cross-Build / build (~1.22.3, 1.22, linux) (push) Has been cancelled
Cross-Build / build (~1.22.3, 1.22, netbsd) (push) Has been cancelled
Cross-Build / build (~1.22.3, 1.22, openbsd) (push) Has been cancelled
Cross-Build / build (~1.22.3, 1.22, solaris) (push) Has been cancelled
Cross-Build / build (~1.22.3, 1.22, windows) (push) Has been cancelled
Cross-Build / build (~1.23.0, 1.23, aix) (push) Has been cancelled
Cross-Build / build (~1.23.0, 1.23, darwin) (push) Has been cancelled
Cross-Build / build (~1.23.0, 1.23, dragonfly) (push) Has been cancelled
Cross-Build / build (~1.23.0, 1.23, freebsd) (push) Has been cancelled
Cross-Build / build (~1.23.0, 1.23, illumos) (push) Has been cancelled
Cross-Build / build (~1.23.0, 1.23, linux) (push) Has been cancelled
Cross-Build / build (~1.23.0, 1.23, netbsd) (push) Has been cancelled
Cross-Build / build (~1.23.0, 1.23, openbsd) (push) Has been cancelled
Cross-Build / build (~1.23.0, 1.23, solaris) (push) Has been cancelled
Cross-Build / build (~1.23.0, 1.23, windows) (push) Has been cancelled

* Allow 0 as weights

Change positive to non-negative

* reverseproxy: allow 0 as weighted round robin value

* test: add more wrr select test

---------

Co-authored-by: peanutduck <peanutduck@yahoo.com>
This commit is contained in:
Sucipto 2024-11-08 05:58:31 +07:00 committed by GitHub
parent b285763969
commit 825fe48e06
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 65 additions and 6 deletions

View File

@ -111,8 +111,8 @@ func (r *WeightedRoundRobinSelection) UnmarshalCaddyfile(d *caddyfile.Dispenser)
if err != nil {
return d.Errf("invalid weight value '%s': %v", weight, err)
}
if weightInt < 1 {
return d.Errf("invalid weight value '%s': weight should be non-zero and positive", weight)
if weightInt < 0 {
return d.Errf("invalid weight value '%s': weight should be non-negative", weight)
}
r.Weights = append(r.Weights, weightInt)
}
@ -136,8 +136,15 @@ func (r *WeightedRoundRobinSelection) Select(pool UpstreamPool, _ *http.Request,
return pool[0]
}
var index, totalWeight int
var weights []int
for _, w := range r.Weights {
if w > 0 {
weights = append(weights, w)
}
}
currentWeight := int(atomic.AddUint32(&r.index, 1)) % r.totalWeight
for i, weight := range r.Weights {
for i, weight := range weights {
totalWeight += weight
if currentWeight < totalWeight {
index = i
@ -145,9 +152,9 @@ func (r *WeightedRoundRobinSelection) Select(pool UpstreamPool, _ *http.Request,
}
}
upstreams := make([]*Upstream, 0, len(r.Weights))
for _, upstream := range pool {
if !upstream.Available() {
upstreams := make([]*Upstream, 0, len(weights))
for i, upstream := range pool {
if !upstream.Available() || r.Weights[i] == 0 {
continue
}
upstreams = append(upstreams, upstream)

View File

@ -131,6 +131,58 @@ func TestWeightedRoundRobinPolicy(t *testing.T) {
}
}
func TestWeightedRoundRobinPolicyWithZeroWeight(t *testing.T) {
pool := testPool()
wrrPolicy := WeightedRoundRobinSelection{
Weights: []int{0, 2, 1},
totalWeight: 3,
}
req, _ := http.NewRequest("GET", "/", nil)
h := wrrPolicy.Select(pool, req, nil)
if h != pool[1] {
t.Error("Expected first weighted round robin host to be second host in the pool.")
}
h = wrrPolicy.Select(pool, req, nil)
if h != pool[2] {
t.Error("Expected second weighted round robin host to be third host in the pool.")
}
h = wrrPolicy.Select(pool, req, nil)
if h != pool[1] {
t.Error("Expected third weighted round robin host to be second host in the pool.")
}
// mark second host as down
pool[1].setHealthy(false)
h = wrrPolicy.Select(pool, req, nil)
if h != pool[2] {
t.Error("Expect select next available host.")
}
h = wrrPolicy.Select(pool, req, nil)
if h != pool[2] {
t.Error("Expect select only available host.")
}
// mark second host as up
pool[1].setHealthy(true)
h = wrrPolicy.Select(pool, req, nil)
if h != pool[1] {
t.Error("Expect select first host on availability.")
}
// test next select in full cycle
expected := []*Upstream{pool[1], pool[2], pool[1], pool[1], pool[2], pool[1]}
for i, want := range expected {
got := wrrPolicy.Select(pool, req, nil)
if want != got {
t.Errorf("Selection %d: got host[%s], want host[%s]", i+1, got, want)
}
}
}
func TestLeastConnPolicy(t *testing.T) {
pool := testPool()
lcPolicy := LeastConnSelection{}