Skip to content

Commit 5665107

Browse files
liverpool8056dndxchronolaw
committed
fix(core): Add a new parameter worker_event_max_payload to kong.conf (#11214)
* With a hard-coded payload size, for some use cases like uploading a big OpenAPI spec in DevPortal or updating a big config entry for plugins, they can not work as expected. With the new parameter, the user can decide the payload size to meet their needs. In this PR, a new parameter, `worker_events_max_payload` is added, which allows to specify the payload size the `worker_events` lib can accept. The default size is 64k, and the max allowed to set is 16M Bytes. The corresponding PR for `worker_events` lib is [#37](Kong/lua-resty-events#37) FTI-4963 * add changelog entry * Update kong.conf.default Co-authored-by: Datong Sun <[email protected]> * add test case and bump lua-resty-events * correct the default value, and add an entry for bumping the version of lua-resty-events * 1. append PR number to the changelog entry of lua-resty-events 2. correct the spec test 3. style * Update CHANGELOG.md --------- Co-authored-by: Datong Sun <[email protected]> Co-authored-by: Chrono <[email protected]>
1 parent 9942c71 commit 5665107

File tree

7 files changed

+146
-8
lines changed

7 files changed

+146
-8
lines changed

.requirements

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ PCRE=8.45
77

88
LUA_KONG_NGINX_MODULE=4d19e8d19c6dbc07eba5cf6f5ebacad95266f928 # 0.6.0
99
LUA_RESTY_LMDB=951926f20b674a0622236a0e331b359df1c02d9b # 1.3.0
10-
LUA_RESTY_EVENTS=2f6fa23eb3d0b76a3b35fd915711200e90bc6732 # 0.1.6
10+
LUA_RESTY_EVENTS=8448a92cec36ac04ea522e78f6496ba03c9b1fd8 # 0.2.0
1111
LUA_RESTY_WEBSOCKET=60eafc3d7153bceb16e6327074e0afc3d94b1316 # 0.4.0
1212
ATC_ROUTER=72cc8fddeac024c54c9c1fa5a25c28a72d79080e # 1.1.0
1313

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,10 @@
151151
[#11099](https://github.com/Kong/kong/pull/11099)
152152
- Bumped kong-lapis from 1.8.3.1 to 1.14.0.2
153153
[#10841](https://github.com/Kong/kong/pull/10841)
154-
- Bumped lua-resty-events from 0.1.4 to 0.1.6
154+
- Bumped lua-resty-events from 0.1.4 to 0.2.0
155155
[#10883](https://github.com/Kong/kong/pull/10883)
156156
[#11083](https://github.com/Kong/kong/pull/11083)
157+
[#11214](https://github.com/Kong/kong/pull/11214)
157158
- Bumped lua-resty-session from 4.0.3 to 4.0.4
158159
[#11011](https://github.com/Kong/kong/pull/11011)
159160
- Bumped OpenSSL from 1.1.1t to 3.1.1

kong.conf.default

+1
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@
269269
# Similarly to `error_template_html`, the template
270270
# is required to contain one single `%s` placeholder for
271271
# the error message.
272+
272273
#------------------------------------------------------------------------------
273274
# HYBRID MODE
274275
#------------------------------------------------------------------------------

kong/conf_loader/init.lua

+2
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,8 @@ local CONF_PARSERS = {
358358
},
359359
},
360360

361+
worker_events_max_payload = { typ = "number" },
362+
361363
upstream_keepalive_pool_size = { typ = "number" },
362364
upstream_keepalive_max_requests = { typ = "number" },
363365
upstream_keepalive_idle_timeout = { typ = "number" },

kong/global.lua

+16-6
Original file line numberDiff line numberDiff line change
@@ -178,21 +178,31 @@ function _GLOBAL.init_worker_events()
178178

179179
-- `kong.configuration.prefix` is already normalized to an absolute path,
180180
-- but `ngx.config.prefix()` is not
181-
local prefix = configuration
182-
and configuration.prefix
183-
or require("pl.path").abspath(ngx.config.prefix())
181+
local prefix = configuration and
182+
configuration.prefix or
183+
require("pl.path").abspath(ngx.config.prefix())
184184

185-
local sock = ngx.config.subsystem == "stream"
186-
and "stream_worker_events.sock"
187-
or "worker_events.sock"
185+
local sock = ngx.config.subsystem == "stream" and
186+
"stream_worker_events.sock" or
187+
"worker_events.sock"
188188

189189
local listening = "unix:" .. prefix .. "/" .. sock
190190

191+
local max_payload_len = configuration and
192+
configuration.worker_events_max_payload
193+
194+
if max_payload_len and max_payload_len > 65535 then -- default is 64KB
195+
ngx.log(ngx.WARN,
196+
"Increasing 'worker_events_max_payload' value has potential " ..
197+
"negative impact on Kong's response latency and memory usage")
198+
end
199+
191200
opts = {
192201
unique_timeout = 5, -- life time of unique event data in lrucache
193202
broker_id = 0, -- broker server runs in nginx worker #0
194203
listening = listening, -- unix socket for broker listening
195204
max_queue_len = 1024 * 50, -- max queue len for events buffering
205+
max_payload_len = max_payload_len, -- max payload size in bytes
196206
}
197207

198208
worker_events = require "resty.events.compat"

kong/templates/kong_defaults.lua

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ cluster_dp_labels = NONE
4545
lmdb_environment_path = dbless.lmdb
4646
lmdb_map_size = 2048m
4747
mem_cache_size = 128m
48+
worker_events_max_payload = 65535
4849
ssl_cert = NONE
4950
ssl_cert_key = NONE
5051
client_ssl = off
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
local helpers = require "spec.helpers"
2+
3+
local worker_events_mock = [[
4+
server {
5+
server_name example.com;
6+
listen %d;
7+
8+
location = /payload {
9+
content_by_lua_block {
10+
local SOURCE = "foo"
11+
local EVENT = ngx.var.http_payload_type
12+
13+
local worker_events = kong.worker_events
14+
local payload_received
15+
16+
local function wait_until(validator, timeout)
17+
local deadline = ngx.now() + (timeout or 5)
18+
local res
19+
repeat
20+
worker_events.poll()
21+
res = validator()
22+
until res or ngx.now() >= deadline
23+
return res
24+
end
25+
26+
-- subscribe
27+
local ok, err = worker_events.register(function(data)
28+
payload_received = data
29+
end, SOURCE, EVENT)
30+
31+
-- when payload is a string
32+
local PAYLOAD = string.rep("X", %d)
33+
34+
-- when payload is a table
35+
if EVENT == "table" then
36+
PAYLOAD = {
37+
foo = "bar",
38+
data = PAYLOAD,
39+
}
40+
end
41+
42+
local ok, err = worker_events.post(SOURCE, EVENT, PAYLOAD)
43+
if not ok then
44+
ngx.status = ngx.HTTP_INTERNAL_SERVER_ERROR
45+
ngx.say("post failed, err: " .. err)
46+
return
47+
end
48+
49+
assert(wait_until(function()
50+
if EVENT == "string" then
51+
return PAYLOAD == payload_received
52+
else
53+
return require("pl.tablex").deepcompare(PAYLOAD, payload_received)
54+
end
55+
end, 1))
56+
57+
ngx.status = ngx.HTTP_OK
58+
ngx.say("ok")
59+
}
60+
}
61+
}
62+
]]
63+
64+
65+
local max_payloads = { 60 * 1024, 140 * 1024, }
66+
67+
68+
for _, max_payload in ipairs(max_payloads) do
69+
local business_port = 34567
70+
local payload_size = 70 * 1024
71+
72+
local fixtures = {
73+
http_mock = {
74+
worker_events = string.format(worker_events_mock,
75+
business_port, payload_size)
76+
},
77+
}
78+
79+
local size_allowed = max_payload > payload_size
80+
local less_or_greater = size_allowed and ">" or "<"
81+
82+
describe("worker_events [when max_payload " .. less_or_greater .. " payload_size]", function()
83+
local strategy = "off"
84+
local test_cases = {"string", "table", }
85+
86+
lazy_setup(function()
87+
assert(helpers.start_kong({
88+
database = strategy,
89+
nginx_conf = "spec/fixtures/custom_nginx.template",
90+
worker_events_max_payload = max_payload,
91+
}, nil, nil, fixtures))
92+
end)
93+
94+
lazy_teardown(function ()
95+
assert(helpers.stop_kong())
96+
end)
97+
98+
for _, payload_type in ipairs(test_cases) do
99+
it("max_payload = " .. max_payload .. ", type = " .. payload_type, function()
100+
101+
local res = helpers.proxy_client(nil, business_port):get(
102+
"/payload", {
103+
headers = {
104+
host = "example.com",
105+
payload_type = payload_type,
106+
}
107+
})
108+
109+
local status_code = 200
110+
local msg = "ok"
111+
112+
if not size_allowed then
113+
status_code = 500
114+
msg = "post failed, err: " ..
115+
"failed to publish event: payload exceeds the limitation (".. max_payload .. ")"
116+
end
117+
118+
local body = assert.res_status(status_code, res)
119+
assert.equal(body, msg)
120+
end)
121+
end
122+
end)
123+
end

0 commit comments

Comments
 (0)