Skip to content

Conversation

nic-6443
Copy link
Member

@nic-6443 nic-6443 commented Sep 24, 2025

Description

In order for the admin API standalone mode to work properly in the stream subsystem, we need to execute the apisix.admin module initialization function like in the HTTP subsystem:

function _M.init_worker()
local function update_config(config)
if not config then
local err
config, err = get_config()
if not config then
core.log.error("failed to get config: ", err)
return
end
end
-- remove metadata key in-place
-- this table is generated by json decode, so there is no need to clone it
config[METADATA_LAST_MODIFIED] = nil
config[METADATA_DIGEST] = nil
config_yaml._update_config(config)
end
events:register(update_config, EVENT_UPDATE, EVENT_UPDATE)
-- due to the event module can not broadcast events between http and stream subsystems,
-- we need to poll the shared dict to keep the config in sync
local last_modified_per_worker
timer_every(1, function ()
if not exiting() then
local config, err = get_config()
if not config then
if err ~= NOT_FOUND_ERR then
core.log.error("failed to get config: ", err)
end
else
local last_modified = config[METADATA_LAST_MODIFIED]
if last_modified_per_worker ~= last_modified then
update_config(config)
last_modified_per_worker = last_modified
end
end
end
end)
patch_schema()
end
. The previous test cases called /apisix/admin/configs API in a prior test case and then test-nginx performed a reload, which led to executing the following code and failed to detect that the backend timer was not started correctly.
if is_use_admin_api() and not shared_dict then
log.info("try to load config from shared dict")
local config, err
shared_dict = ngx_shared["standalone-config"] -- init shared dict in current worker
if not shared_dict then
log.error("failed to read config from shared dict: shared dict not found")
goto SKIP_SHARED_DICT
end
config, err = shared_dict:get("config")
if not config then
if err then -- if the key does not exist, the return values are both nil
log.error("failed to read config from shared dict: ", err)
end
log.info("no config found in shared dict")
goto SKIP_SHARED_DICT
end
log.info("startup config loaded from shared dict: ", config)
config, err = json.decode(tostring(config))
if not config then
log.error("failed to decode config from shared dict: ", err)
goto SKIP_SHARED_DICT
end
_M._update_config(config)
log.info("config loaded from shared dict")
::SKIP_SHARED_DICT::
if not shared_dict then
log.crit(_M.ERR_NO_SHARED_DICT)
-- fill that value to make the worker not try to read from shared dict again
shared_dict = "error"
end
end

Which issue(s) this PR fixes:

Fixes #

Checklist

  • I have explained the need for this PR and the problem it solves
  • I have explained the changes or the new features added to this PR
  • I have added tests corresponding to this change
  • I have updated the documentation to reflect this change
  • I have verified that this change is backward compatible (If not, please discuss on the APISIX mailing list first)

@dosubot dosubot bot added size:M This PR changes 30-99 lines, ignoring generated files. bug Something isn't working labels Sep 24, 2025
@nic-6443 nic-6443 merged commit 208657b into apache:master Sep 24, 2025
29 of 35 checks passed
@nic-6443 nic-6443 deleted the nic/fix-stream-route2 branch September 24, 2025 10:40
jizhuozhi pushed a commit to jizhuozhi/apisix that referenced this pull request Oct 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants