This is an automated email from the ASF dual-hosted git repository.

membphis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git


The following commit(s) were added to refs/heads/master by this push:
     new 3950e4a  chore: add safe limit to avoid infinite loop caused by bug 
(#3682)
3950e4a is described below

commit 3950e4a781b2d11bee5ecf4d62229d0a36ce36ff
Author: 罗泽轩 <spacewander...@gmail.com>
AuthorDate: Sat Feb 27 20:02:07 2021 +0800

    chore: add safe limit to avoid infinite loop caused by bug (#3682)
---
 apisix/balancer/least_conn.lua | 5 ++++-
 apisix/balancer/roundrobin.lua | 9 ++++++++-
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/apisix/balancer/least_conn.lua b/apisix/balancer/least_conn.lua
index a1d37c7..1cfdbf9 100644
--- a/apisix/balancer/least_conn.lua
+++ b/apisix/balancer/least_conn.lua
@@ -31,7 +31,10 @@ end
 
 function _M.new(up_nodes, upstream)
     local servers_heap = binaryHeap.minUnique(least_score)
+    local safe_limit = 0
     for server, weight in pairs(up_nodes) do
+        safe_limit = safe_limit + 1
+
         local score = 1 / weight
         -- Note: the argument order of insert is different from others
         servers_heap:insert({
@@ -47,7 +50,7 @@ function _M.new(up_nodes, upstream)
             local server, info, err
             if ctx.balancer_tried_servers then
                 local tried_server_list = {}
-                while true do
+                for i = 1, safe_limit do
                     server, info = servers_heap:peek()
                     if server == nil then
                         err = "all upstream servers tried"
diff --git a/apisix/balancer/roundrobin.lua b/apisix/balancer/roundrobin.lua
index 7d4a374..a9469ca 100644
--- a/apisix/balancer/roundrobin.lua
+++ b/apisix/balancer/roundrobin.lua
@@ -18,12 +18,19 @@
 local roundrobin  = require("resty.roundrobin")
 local core = require("apisix.core")
 local nkeys = core.table.nkeys
+local pairs = pairs
 
 
 local _M = {}
 
 
 function _M.new(up_nodes, upstream)
+    local safe_limit = 0
+    for _, weight in pairs(up_nodes) do
+        -- the weight can be zero
+        safe_limit = safe_limit + weight + 1
+    end
+
     local picker = roundrobin:new(up_nodes)
     local nodes_count = nkeys(up_nodes)
     return {
@@ -34,7 +41,7 @@ function _M.new(up_nodes, upstream)
             end
 
             local server, err
-            while true do
+            for i = 1, safe_limit do
                 server, err = picker:find()
                 if not server then
                     return nil, err

Reply via email to