Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(runloop/balancer): clean the code of round robin algo #11315

Merged
merged 8 commits into from
Sep 13, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 43 additions & 23 deletions kong/runloop/balancer/round_robin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ end


function roundrobin_algorithm:afterHostUpdate()
local new_wheel = {}
local total_points = 0
local total_weight = 0
local divisor = 0
Expand All @@ -56,11 +55,15 @@ function roundrobin_algorithm:afterHostUpdate()
end

-- add all addresses to the wheel
for _, targets in ipairs(targets) do
for _, address in ipairs(targets.addresses) do
local new_wheel = {}
local idx = 1

for _, target in ipairs(targets) do
for _, address in ipairs(target.addresses) do
local address_points = address.weight / divisor
for _ = 1, address_points do
new_wheel[#new_wheel + 1] = address
new_wheel[idx] = address
idx = idx + 1
chronolaw marked this conversation as resolved.
Show resolved Hide resolved
end
end
end
Expand All @@ -75,6 +78,7 @@ function roundrobin_algorithm:getPeer(cacheOnly, handle, hashValue)
if handle then
-- existing handle, so it's a retry
handle.retryCount = handle.retryCount + 1

else
-- no handle, so this is a first try
handle = {} -- self:getHandle() -- no GC specific handler needed
Expand All @@ -84,6 +88,7 @@ function roundrobin_algorithm:getPeer(cacheOnly, handle, hashValue)
local starting_pointer = self.pointer
local address
local ip, port, hostname

repeat
self.pointer = self.pointer + 1

Expand All @@ -92,36 +97,51 @@ function roundrobin_algorithm:getPeer(cacheOnly, handle, hashValue)
end

address = self.wheel[self.pointer]
if address ~= nil and address.available and not address.disabled then
ip, port, hostname = balancers.getAddressPeer(address, cacheOnly)
if ip then
-- success, update handle
handle.address = address
return ip, port, hostname, handle

elseif port == balancers.errors.ERR_DNS_UPDATED then
-- if healty we just need to try again
if not self.balancer.healthy then
return nil, balancers.errors.ERR_BALANCER_UNHEALTHY
end
elseif port == balancers.errors.ERR_ADDRESS_UNAVAILABLE then
ngx.log(ngx.DEBUG, "found address but it was unavailable. ",
" trying next one.")
else
-- an unknown error occurred
return nil, port
if not address or not address.available or address.disabled then
oowl marked this conversation as resolved.
Show resolved Hide resolved
goto continue
end

-- address ~= nil and address.available and not address.disabled

ip, port, hostname = balancers.getAddressPeer(address, cacheOnly)

if ip then
-- success, update handle
handle.address = address
return ip, port, hostname, handle
end

-- no ip, port is an error hint

if port == balancers.errors.ERR_DNS_UPDATED then
-- if healthy we just need to try again
if self.balancer.healthy then
goto continue
end

-- not healthy
return nil, balancers.errors.ERR_BALANCER_UNHEALTHY
end

if port == balancers.errors.ERR_ADDRESS_UNAVAILABLE then
ngx.log(ngx.DEBUG, "found address but it was unavailable. ",
" trying next one.")
goto continue
end

-- an unknown error occurred
do return nil, port end

::continue::

until self.pointer == starting_pointer

return nil, balancers.errors.ERR_NO_PEERS_AVAILABLE
end


function roundrobin_algorithm.new(opts)
assert(type(opts) == "table", "Expected an options table, but got: "..type(opts))
assert(type(opts) == "table", "Expected an options table, but got: " .. type(opts))
oowl marked this conversation as resolved.
Show resolved Hide resolved

local balancer = opts.balancer

Expand Down
Loading