Skip to content

Commit

Permalink
feat: support xrpc protocol custom protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
Foo Bar authored and AlinsRan committed Sep 20, 2024
1 parent e5f79c8 commit fc863f5
Show file tree
Hide file tree
Showing 2 changed files with 565 additions and 0 deletions.
63 changes: 63 additions & 0 deletions lib/resty/healthcheck.lua
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ local EMPTY = setmetatable({},{
-- Counters: a 32-bit shm integer can hold up to four 8-bit counters.
local CTR_SUCCESS = 0x00000001
local CTR_HTTP = 0x00000100
local CTR_XRPC = 0x00001000
local CTR_TCP = 0x00010000
local CTR_TIMEOUT = 0x01000000

Expand All @@ -63,6 +64,7 @@ local MASK_SUCCESS = 0x000000ff
local COUNTER_NAMES = {
[CTR_SUCCESS] = "SUCCESS",
[CTR_HTTP] = "HTTP",
[CTR_XRPC] = "XRPC",
[CTR_TCP] = "TCP",
[CTR_TIMEOUT] = "TIMEOUT",
}
Expand Down Expand Up @@ -659,6 +661,9 @@ function checker:report_failure(ip, port, hostname, check)
if self.checks[check or "passive"].type == "tcp" then
limit = checks.unhealthy.tcp_failures
ctr_type = CTR_TCP
elseif self.checks[check or "passive"].type == "xrpc" then
limit = checks.unhealthy.failures
ctr_type = CTR_XRPC
else
limit = checks.unhealthy.http_failures
ctr_type = CTR_HTTP
Expand Down Expand Up @@ -725,6 +730,34 @@ function checker:report_http_status(ip, port, hostname, http_status, check)

end


function checker:report_xrpc_status(ip, port, hostname, status, check)
status = tonumber(status) or 0

if check ~= "active" then
return
end

local checks = self.checks[check or "active"]

local status_type, limit, ctr
if checks.healthy.statuses[status] then
status_type = "healthy"
limit = checks.healthy.successes
ctr = CTR_SUCCESS
elseif checks.unhealthy.statuses[status]
or status == 0 then
status_type = "unhealthy"
limit = checks.unhealthy.failures
ctr = CTR_XRPC
else
return
end

return incr_counter(self, status_type, ip, port, hostname, limit, ctr)

end

--- Report a failure on TCP level.
-- If `unhealthy.tcp_failures` is set to zero in the configuration,
-- this function is a no-op and returns `true`.
Expand Down Expand Up @@ -857,6 +890,23 @@ end

-- Runs a single healthcheck probe
function checker:run_single_check(ip, port, hostname, hostheader)
if self.checks.active.type == "xrpc" then
local ok, status = self.checks.active.handler({
host = ip,
port = port,
domain = hostname,
}, self.xrpc_conf)

if not ok then
return self:report_failure(ip, port, hostname, "active")
end

if status then
return self:report_xrpc_status(ip, port, hostname, status, "active")
end

return self:report_success(ip, port, hostname, "active")
end

local sock, err = ngx.socket.tcp()
if not sock then
Expand Down Expand Up @@ -1277,15 +1327,20 @@ local defaults = {
concurrency = 10,
http_path = "/",
https_verify_certificate = true,
handler = NO_DEFAULT,
xrpc_conf = {},
healthy = {
interval = 0, -- 0 = disabled by default
http_statuses = { 200, 302 },
statuses = { 200, 302 },
successes = 2,
},
unhealthy = {
interval = 0, -- 0 = disabled by default
http_statuses = { 429, 404,
500, 501, 502, 503, 504, 505 },
statuses = { 500, 501 },
failures = 2,
tcp_failures = 2,
timeouts = 3,
http_failures = 5,
Expand Down Expand Up @@ -1325,6 +1380,7 @@ do
http = true,
tcp = true,
https = true,
xrpc = true,
}
check_valid_type = function(var, val)
assert(valid_types[val],
Expand Down Expand Up @@ -1399,6 +1455,11 @@ function _M.new(opts)
self.test_get_counter = test_get_counter
end

if self.checks.active.type == "xrpc" then
assert(self.checks.active.handler, "required option 'checks.active.handler' is missing")
assert(self.checks.active.unhealthy.failures < 255, "checks.active.unhealthy.tcp_failures must be at most 254")
end

assert(self.name, "required option 'name' is missing")
assert(self.shm_name, "required option 'shm_name' is missing")

Expand All @@ -1420,6 +1481,8 @@ function _M.new(opts)
to_set(self.checks.active.healthy, "http_statuses")
to_set(self.checks.passive.unhealthy, "http_statuses")
to_set(self.checks.passive.healthy, "http_statuses")
to_set(self.checks.active.healthy, "statuses")
to_set(self.checks.active.unhealthy, "statuses")

-- decorate with methods and constants
self.events = EVENTS
Expand Down
Loading

0 comments on commit fc863f5

Please sign in to comment.