Skip to content

Commit 095262f

Browse files
committed
api: restore httpd server on config reload
In case when httpd server serves metrics-export endpoint, updating one server causes a deletion of its routes. After this patch role updates httpd server on config reload and its routes. Closes #38
1 parent 4285f4f commit 095262f

File tree

3 files changed

+61
-2
lines changed

3 files changed

+61
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
### Fixed
1313

14+
- Routes deletion on config reload (#38).
15+
1416
### Changed
1517

1618
## 0.3.1 - 2025-07-07

roles/metrics-export.lua

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ local function disable_server(name)
327327

328328
if server ~= nil then
329329
if server.httpd_name ~= nil then
330-
for path, _ in pairs(server.routes) do
330+
for path in pairs(server.routes) do
331331
server.httpd:delete(path)
332332
end
333333
else
@@ -402,6 +402,9 @@ local function apply_http(conf)
402402
-- if it isn't in applying config.
403403
table.insert(listen_servers_to_start, http_servers[target.value])
404404
end
405+
elseif target.httpd_name ~= nil then
406+
-- Update httpd value because it could change.
407+
http_servers[target.value].httpd = httpd_role.get_server(target.httpd_name)
405408
end
406409

407410
local server = http_servers[target.value]
@@ -427,7 +430,7 @@ local function apply_http(conf)
427430

428431
-- Add new routes.
429432
for path, endpoint in pairs(new_routes) do
430-
if old_routes[path] == nil then
433+
if old_routes[path] == nil or httpd.iroutes[path] == nil then
431434
httpd:route({
432435
method = "GET",
433436
path = path,

test/integration/reload_config_test.lua

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ local yaml = require('yaml')
33
local socket = require('socket')
44
local helpers = require('test.helpers')
55
local server = require('test.helpers.server')
6+
local http_client = require('http.client'):new()
67

78
local t = require('luatest')
89
local g = t.group()
@@ -57,6 +58,26 @@ local function change_listen_target_in_config(cg, old_addr, new_addr)
5758
file:close()
5859
end
5960

61+
local function change_http_addr_in_config(cg, new_addr, server_name)
62+
if server_name == nil then
63+
server_name = 'default'
64+
end
65+
66+
local file = fio.open(fio.pathjoin(cg.workdir, 'config.yaml'), {'O_RDONLY'})
67+
t.assert(file ~= nil)
68+
69+
local cfg = file:read()
70+
file:close()
71+
72+
cfg = yaml.decode(cfg)
73+
cfg.groups['group-001'].replicasets['replicaset-001'].
74+
instances.master.roles_cfg['roles.httpd'][server_name].listen = new_addr
75+
76+
file = fio.open(fio.pathjoin(cg.workdir, 'config.yaml'), {'O_CREAT', 'O_WRONLY', 'O_TRUNC'}, tonumber('644', 8))
77+
file:write(yaml.encode(cfg))
78+
file:close()
79+
end
80+
6081
g.test_reload_config_update_addr = function(cg)
6182
cg.server = server:new({
6283
config_file = fio.pathjoin(cg.workdir, 'config.yaml'),
@@ -100,3 +121,36 @@ g.test_reload_config_global_addr_conflict = function(cg)
100121
function() cg.server:eval("require('config'):reload()") end
101122
)
102123
end
124+
125+
g.test_reload_config_routes_exists = function(cg)
126+
cg.server = server:new({
127+
config_file = fio.pathjoin(cg.workdir, 'config.yaml'),
128+
chdir = cg.workdir,
129+
alias = 'master',
130+
workdir = cg.workdir,
131+
})
132+
133+
cg.server:start({wait_until_ready = true})
134+
135+
local response = http_client:get('localhost:8085/metrics/prometheus')
136+
t.assert_equals(response.status, 200)
137+
t.assert(response.body)
138+
139+
local _, err = cg.server:eval("require('config'):reload()")
140+
t.assert_not(err)
141+
142+
response = http_client:get('localhost:8085/metrics/prometheus')
143+
t.assert_equals(response.status, 200)
144+
t.assert(response.body)
145+
146+
change_http_addr_in_config(cg, 8088)
147+
_, err = cg.server:eval("require('config'):reload()")
148+
t.assert_not(err)
149+
150+
response = http_client:get('localhost:8085/metrics/prometheus')
151+
t.assert_equals(response.status, 595)
152+
153+
response = http_client:get('localhost:8088/metrics/prometheus')
154+
t.assert_equals(response.status, 200)
155+
t.assert(response.body)
156+
end

0 commit comments

Comments
 (0)