Skip to content

Commit 56fd8ad

Browse files
author
doujiang
authored
bugfix: should force convert weight to a number since it may cause dead loop when weight is a string type "0". (openresty#40)
1 parent 2e1848e commit 56fd8ad

File tree

3 files changed

+82
-19
lines changed

3 files changed

+82
-19
lines changed

README.markdown

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ The `id` should be `table.concat({host, string.char(0), port})` like the nginx c
135135
when we need to keep consistency with nginx chash.
136136

137137
The `id` can be any string value when we do not need to keep consistency with nginx chash.
138+
The `weight` should be a non negative integer.
138139

139140
```lua
140141
local nodes = {

lib/resty/balancer/utils.lua

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,10 @@ do
1111
new_tab = function (narr, nrec) return {} end
1212
end
1313
end
14-
1514
_M.new_tab = new_tab
1615

17-
local copy
18-
do
19-
local ok
20-
ok, copy = pcall(require, "table.clone")
21-
if not ok or type(copy) ~= "function" then
22-
copy = function(nodes)
23-
local newnodes = new_tab(0, 0)
24-
for id, weight in pairs(nodes) do
25-
newnodes[id] = weight
26-
end
27-
28-
return newnodes
29-
end
30-
end
31-
end
32-
_M.copy = copy
3316

34-
local nkeys
17+
local nkeys, tab_nkeys
3518
do
3619
local ok
3720
ok, nkeys = pcall(require, "table.nkeys")
@@ -43,9 +26,22 @@ do
4326
end
4427
return count
4528
end
29+
30+
else
31+
tab_nkeys = nkeys
4632
end
4733
end
48-
4934
_M.nkeys = nkeys
5035

36+
37+
function _M.copy(nodes)
38+
local newnodes = new_tab(0, tab_nkeys and tab_nkeys(nodes) or 4)
39+
for id, weight in pairs(nodes) do
40+
newnodes[id] = tonumber(weight)
41+
end
42+
43+
return newnodes
44+
end
45+
46+
5147
return _M

t/roundrobin.t

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,69 @@ GET /t
146146
false
147147
--- no_error_log
148148
[error]
149+
150+
151+
152+
=== TEST 4: weight is "0"
153+
--- http_config eval: $::HttpConfig
154+
--- config
155+
location /t {
156+
content_by_lua_block {
157+
math.randomseed(9975098)
158+
159+
local roundrobin = require "resty.roundrobin"
160+
161+
local servers = {
162+
["server1"] = "0",
163+
["server2"] = "1",
164+
["server3"] = "0",
165+
["server4"] = "0",
166+
}
167+
168+
local rr = roundrobin:new(servers, true)
169+
local id = rr:find()
170+
171+
ngx.say("id: ", id)
172+
}
173+
}
174+
--- request
175+
GET /t
176+
--- response_body
177+
id: server2
178+
--- no_error_log
179+
[error]
180+
181+
182+
183+
=== TEST 5: all weights are 0, behavior like weights are 1.
184+
It's not recommends to use 0, this test just make sure it won't be worse, like crash.
185+
--- http_config eval: $::HttpConfig
186+
--- config
187+
location /t {
188+
content_by_lua_block {
189+
math.randomseed(9975098)
190+
191+
local roundrobin = require "resty.roundrobin"
192+
193+
local servers = {
194+
["server1"] = 0,
195+
["server2"] = 0,
196+
["server3"] = 0,
197+
["server4"] = 0,
198+
}
199+
200+
local rr = roundrobin:new(servers, true)
201+
202+
for i = 1, 4 do
203+
local id = rr:find()
204+
end
205+
206+
ngx.say("ok")
207+
}
208+
}
209+
--- request
210+
GET /t
211+
--- response_body
212+
ok
213+
--- no_error_log
214+
[error]

0 commit comments

Comments
 (0)