Skip to content

Commit 496cb68

Browse files
fix(ai-proxy-multi): guard construct_upstream in healthcheck timers (#13592)
1 parent df0a284 commit 496cb68

2 files changed

Lines changed: 666 additions & 11 deletions

File tree

apisix/healthcheck_manager.lua

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ local function timer_create_checker()
179179
if not res_conf then
180180
goto continue
181181
end
182-
local upstream
182+
local ok, upstream, err
183183
local plugin_name = get_plugin_name(resource_path)
184184
if plugin_name and plugin_name ~= "" then
185185
local _, sub_path = config_util.parse_path(resource_path)
@@ -189,7 +189,14 @@ local function timer_create_checker()
189189
--- callback construct_upstream to create an upstream dynamically
190190
local upstream_constructor_config = jp.value(res_conf.value, json_path)
191191
local plugin = require("apisix.plugins." .. plugin_name)
192-
upstream = plugin.construct_upstream(upstream_constructor_config)
192+
ok, upstream, err = pcall(plugin.construct_upstream, upstream_constructor_config)
193+
if not ok or not upstream then
194+
err = err or upstream
195+
core.log.error("[creating checker] unable to construct upstream",
196+
" for plugin: ", plugin_name, ", resource path: ", resource_path,
197+
", json path: ", json_path, ", error: ", err)
198+
goto continue
199+
end
193200
upstream.resource_key = resource_path
194201
else
195202
upstream = res_conf.value.upstream or res_conf.value
@@ -237,7 +244,7 @@ local function timer_working_pool_check()
237244
local res_conf = resource.fetch_latest_conf(resource_path)
238245
local need_destroy = true
239246
if res_conf and res_conf.value then
240-
local upstream
247+
local ok, upstream, err
241248
local plugin_name = get_plugin_name(resource_path)
242249
if plugin_name and plugin_name ~= "" then
243250
local _, sub_path = config_util.parse_path(resource_path)
@@ -247,17 +254,37 @@ local function timer_working_pool_check()
247254
--- callback construct_upstream to create an upstream dynamically
248255
local upstream_constructor_config = jp.value(res_conf.value, json_path)
249256
local plugin = require("apisix.plugins." .. plugin_name)
250-
upstream = plugin.construct_upstream(upstream_constructor_config)
251-
upstream.resource_key = resource_path
257+
ok, upstream, err = pcall(plugin.construct_upstream, upstream_constructor_config)
258+
if not ok or not upstream then
259+
-- a nil constructor config means the instance was removed, so let
260+
-- the checker be destroyed; otherwise keep it through a transient failure
261+
if upstream_constructor_config ~= nil then
262+
need_destroy = false
263+
end
264+
err = err or upstream or "unknown error"
265+
upstream = nil
266+
local err_msg = "[checking checker] unable to construct upstream for plugin: "
267+
.. plugin_name .. ", resource path: " .. resource_path
268+
.. ", json path: " .. json_path .. ", error: " .. err
269+
if not ok then
270+
core.log.error(err_msg)
271+
else
272+
core.log.warn(err_msg)
273+
end
274+
else
275+
upstream.resource_key = resource_path
276+
end
252277
else
253278
upstream = res_conf.value.upstream or res_conf.value
254279
end
255-
local current_ver = upstream_utils.version(res_conf.modifiedIndex,
256-
upstream._nodes_ver)
257-
core.log.info("checking working pool for resource: ", resource_path,
258-
" current version: ", current_ver, " item version: ", item.version)
259-
if item.version == current_ver then
260-
need_destroy = false
280+
if upstream then
281+
local current_ver = upstream_utils.version(res_conf.modifiedIndex,
282+
upstream._nodes_ver)
283+
core.log.info("checking working pool for resource: ", resource_path,
284+
" current version: ", current_ver, " item version: ", item.version)
285+
if item.version == current_ver then
286+
need_destroy = false
287+
end
261288
end
262289
end
263290

0 commit comments

Comments
 (0)