Skip to content

Commit 3807cd5

Browse files
ElvinEfendidoujiang24
authored andcommitted
feature: Round Robin with optional random start (openresty#26)
* Round Robin with optional random start * make random start a default and only behaviour
1 parent 0fb8a79 commit 3807cd5

File tree

3 files changed

+74
-5
lines changed

3 files changed

+74
-5
lines changed

README.markdown

+1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ Synopsis
9898

9999
local rr_up = package.loaded.my_rr_up
100100

101+
-- Note that Round Robin picks the first server randomly
101102
local server = rr_up:find()
102103

103104
assert(b.set_current_peer(server))

lib/resty/roundrobin.lua

+20-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ local pairs = pairs
33
local next = next
44
local tonumber = tonumber
55
local setmetatable = setmetatable
6+
local math_random = math.random
67

78

89
local _M = {}
@@ -46,18 +47,35 @@ local function get_gcd(nodes)
4647
return only_key, gcd, max_weight
4748
end
4849

50+
local function get_random_node_id(nodes)
51+
local count = 0
52+
for _, _ in pairs(nodes) do
53+
count = count + 1
54+
end
55+
56+
local id = nil
57+
local random_index = math_random(count)
58+
59+
for _ = 1, random_index do
60+
id = next(nodes, id)
61+
end
62+
63+
return id
64+
end
65+
4966

5067
function _M.new(_, nodes)
5168
local newnodes = copy(nodes)
5269
local only_key, gcd, max_weight = get_gcd(newnodes)
70+
local last_id = get_random_node_id(nodes)
5371

5472
local self = {
5573
nodes = newnodes, -- it's safer to copy one
5674
only_key = only_key,
5775
max_weight = max_weight,
5876
gcd = gcd,
5977
cw = max_weight,
60-
last_id = nil,
78+
last_id = last_id,
6179
}
6280
return setmetatable(self, mt)
6381
end
@@ -68,7 +86,7 @@ function _M.reinit(self, nodes)
6886
self.only_key, self.gcd, self.max_weight = get_gcd(newnodes)
6987

7088
self.nodes = newnodes
71-
self.last_id = nil
89+
self.last_id = get_random_node_id(nodes)
7290
self.cw = self.max_weight
7391
end
7492

t/roundrobin.t

+53-3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ __DATA__
2828
--- config
2929
location /t {
3030
content_by_lua_block {
31+
math.randomseed(75098)
32+
3133
local roundrobin = require "resty.roundrobin"
3234
3335
local servers = {
@@ -53,7 +55,6 @@ GET /t
5355
gcd: 2
5456
id: server1
5557
id: server1
56-
id: server1
5758
id: server2
5859
id: server1
5960
id: server2
@@ -65,6 +66,7 @@ id: server2
6566
id: server1
6667
id: server2
6768
id: server3
69+
id: server1
6870
--- no_error_log
6971
[error]
7072
@@ -75,6 +77,8 @@ id: server3
7577
--- config
7678
location /t {
7779
content_by_lua_block {
80+
math.randomseed(75098)
81+
7882
local roundrobin = require "resty.roundrobin"
7983
8084
local servers = {
@@ -104,8 +108,54 @@ id: server3
104108
--- request
105109
GET /t
106110
--- response_body
107-
server1: 50001
111+
server1: 50000
108112
server3: 16666
109-
server2: 33333
113+
server2: 33334
114+
--- no_error_log
115+
[error]
116+
117+
118+
119+
=== TEST 3: random start
120+
--- http_config eval: $::HttpConfig
121+
--- config
122+
location /t {
123+
content_by_lua_block {
124+
math.randomseed(9975098)
125+
126+
local roundrobin = require "resty.roundrobin"
127+
128+
local servers = {
129+
["server1"] = 1,
130+
["server2"] = 1,
131+
["server3"] = 1,
132+
["server4"] = 1,
133+
}
134+
135+
local rr = roundrobin:new(servers, true)
136+
local id = rr:find()
137+
ngx.say(id)
138+
139+
math.randomseed(11175098)
140+
141+
local new_servers = {
142+
["server1"] = 1,
143+
["server2"] = 1,
144+
["server3"] = 1,
145+
["server4"] = 1,
146+
["server5"] = 1,
147+
["server6"] = 1,
148+
}
149+
150+
rr:reinit(new_servers)
151+
id = rr:find()
152+
ngx.say(id)
153+
}
154+
}
155+
--- request
156+
GET /t
157+
--- response_body
158+
server2
159+
server5
110160
--- no_error_log
111161
[error]

0 commit comments

Comments
 (0)