Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: enable balancer phase for plugins #4549

Merged
merged 4 commits into from
Jul 14, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions apisix/balancer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,9 @@ do
end


function _M.run(route, ctx)
function _M.run(route, ctx, plugin_funcs)
local server, err
local header_changed

if ctx.picked_server then
-- use the server picked in the access phase
Expand All @@ -300,15 +301,24 @@ function _M.run(route, ctx)
return core.response.exit(502)
end

plugin_funcs("balancer")

local pass_host = ctx.pass_host
if pass_host == "node" and balancer.recreate_request then
local host = server.domain or server.host
if host ~= ctx.var.upstream_host then
-- retried node has a different host
ctx.var.upstream_host = host
balancer.recreate_request()
header_changed = true
end
end

end

local _, run = plugin_funcs("balancer")
Copy link
Contributor

@starsz starsz Jul 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will run balancer twice?
Line 312 and line 326 ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in the new commit

-- always recreate request as the request may be changed by plugins
if (run or header_changed) and balancer.recreate_request then
balancer.recreate_request()
end

core.log.info("proxy request to ", server.host, ":", server.port)
Expand Down
9 changes: 4 additions & 5 deletions apisix/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -551,11 +551,10 @@ local function common_phase(phase_name)

if api_ctx.script_obj then
script.run(phase_name, api_ctx)
else
plugin.run_plugin(phase_name, nil, api_ctx)
return api_ctx, true
end

return api_ctx
return plugin.run_plugin(phase_name, nil, api_ctx)
end


Expand Down Expand Up @@ -706,7 +705,7 @@ function _M.http_balancer_phase()
return core.response.exit(500)
end

load_balancer.run(api_ctx.matched_route, api_ctx)
load_balancer.run(api_ctx.matched_route, api_ctx, common_phase)
end


Expand Down Expand Up @@ -916,7 +915,7 @@ function _M.stream_balancer_phase()
return ngx_exit(1)
end

load_balancer.run(api_ctx.matched_route, api_ctx)
load_balancer.run(api_ctx.matched_route, api_ctx, common_phase)
end


Expand Down
7 changes: 5 additions & 2 deletions apisix/plugin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,7 @@ end


function _M.run_plugin(phase, plugins, api_ctx)
local plugin_run = false
api_ctx = api_ctx or ngx.ctx.api_ctx
if not api_ctx then
return
Expand All @@ -639,6 +640,7 @@ function _M.run_plugin(phase, plugins, api_ctx)
for i = 1, #plugins, 2 do
local phase_func = plugins[i][phase]
if phase_func then
plugin_run = true
local code, body = phase_func(plugins[i + 1], api_ctx)
if code or body then
if is_http then
Expand All @@ -657,17 +659,18 @@ function _M.run_plugin(phase, plugins, api_ctx)
end
end
end
return api_ctx
return api_ctx, plugin_run
end

for i = 1, #plugins, 2 do
local phase_func = plugins[i][phase]
if phase_func then
plugin_run = true
phase_func(plugins[i + 1], api_ctx)
end
end

return api_ctx
return api_ctx, plugin_run
end


Expand Down
2 changes: 1 addition & 1 deletion t/debug/debug-mode.t
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ passed
GET /hello
--- yaml_config eval: $::yaml_config
--- response_headers
Apisix-Plugins: response-rewrite, limit-conn, limit-count, response-rewrite
Apisix-Plugins: response-rewrite, limit-conn, limit-count, response-rewrite, response-rewrite
--- response_body
yes
--- error_log
Expand Down
16 changes: 16 additions & 0 deletions t/lib/server.lua
Original file line number Diff line number Diff line change
Expand Up @@ -418,4 +418,20 @@ function _M.server_error()
end


function _M.log_request()
ngx.log(ngx.WARN, "uri: ", ngx.var.uri)
local headers = ngx.req.get_headers()

local keys = {}
for k in pairs(headers) do
table.insert(keys, k)
end
table.sort(keys)

for _, key in ipairs(keys) do
ngx.log(ngx.WARN, key, ": ", headers[key])
end
end


return _M
104 changes: 104 additions & 0 deletions t/plugin/serverless.t
Original file line number Diff line number Diff line change
Expand Up @@ -679,3 +679,107 @@ GET /hello
--- error_log
default phase: access
match uri /hello



=== TEST 23: run in the balancer phase
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"plugins": {
"serverless-pre-function": {
"phase": "balancer",
"functions" : ["return function(conf, ctx) ngx.req.set_header('X-SERVERLESS', ctx.balancer_ip) end"]
}
},
"upstream": {
"nodes": {
"127.0.0.2:1979": 100000,
"127.0.0.1:1980": 1
},
"type": "chash",
"key": "remote_addr"
},
"uri": "/log_request"
}]]
)

if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed
--- no_error_log
[error]



=== TEST 24: check plugin
--- request
GET /log_request
--- skip_nginx: 4: < 1.19.3
--- grep_error_log eval
qr/(proxy request to \S+|x-serverless: [\d.]+)/
--- grep_error_log_out
proxy request to 127.0.0.2:1979
proxy request to 127.0.0.1:1980
x-serverless: 127.0.0.1



=== TEST 25: exit in the balancer phase
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"plugins": {
"serverless-pre-function": {
"phase": "balancer",
"functions" : ["return function(conf, ctx) ngx.exit(403) end"]
}
},
"upstream": {
"nodes": {
"127.0.0.2:1979": 100000,
"127.0.0.1:1980": 1
},
"type": "chash",
"key": "remote_addr"
},
"uri": "/log_request"
}]]
)

if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed
--- no_error_log
[error]



=== TEST 26: check plugin
--- request
GET /log_request
--- error_code: 403
--- no_error_log
[error]