diff --git a/kong/runloop/balancer/round_robin.lua b/kong/runloop/balancer/round_robin.lua index 674c32fb711b..0dd0e96904ab 100644 --- a/kong/runloop/balancer/round_robin.lua +++ b/kong/runloop/balancer/round_robin.lua @@ -29,7 +29,6 @@ end function roundrobin_algorithm:afterHostUpdate() - local new_wheel = {} local total_points = 0 local total_weight = 0 local divisor = 0 @@ -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 end end end @@ -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 @@ -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 @@ -92,28 +97,43 @@ 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 + 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 @@ -121,7 +141,7 @@ 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)) local balancer = opts.balancer