Skip to content

Commit f3472cd

Browse files
committed
Proxy round robin balancer uses next target for retried requests
1 parent 179e74f commit f3472cd

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

middleware/proxy.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -240,13 +240,28 @@ func (b *roundRobinBalancer) Next(c echo.Context) *ProxyTarget {
240240
return b.targets[0]
241241
}
242242

243-
// reset the index if out of bounds
244-
if b.i >= len(b.targets) {
245-
b.i = 0
243+
var i int
244+
const lastIdxKey = "_round_robin_last_index"
245+
// This request is a retry, start from the index of the previous
246+
// target to ensure we don't attempt to retry the request with
247+
// the same failed target
248+
if c.Get(lastIdxKey) != nil {
249+
i = c.Get(lastIdxKey).(int)
250+
i++
251+
if i >= len(b.targets) {
252+
i = 0
253+
}
254+
// This is a first time request, use the global index
255+
} else {
256+
i = b.i
257+
b.i++
258+
if b.i >= len(b.targets) {
259+
b.i = 0
260+
}
246261
}
247-
t := b.targets[b.i]
248-
b.i++
249-
return t
262+
263+
c.Set(lastIdxKey, i)
264+
return b.targets[i]
250265
}
251266

252267
// Proxy returns a Proxy middleware.

middleware/proxy_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ func TestProxyRetryWithBackendTimeout(t *testing.T) {
621621
req := httptest.NewRequest(http.MethodGet, "/", nil)
622622
rec := httptest.NewRecorder()
623623
e.ServeHTTP(rec, req)
624-
assert.Contains(t, []int{200, 502}, rec.Code)
624+
assert.Equal(t, 200, rec.Code)
625625
}()
626626
}
627627

0 commit comments

Comments
 (0)