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

dynamic_hook: cumulative changes #13085

Merged
merged 9 commits into from
May 27, 2024
81 changes: 44 additions & 37 deletions kong/dynamic_hook/init.lua
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
local ngx = ngx
local type = type
local pcall = pcall
local select = select
local ipairs = ipairs
local assert = assert
local ngx_log = ngx.log
local ngx_WARN = ngx.WARN
local ngx = ngx
local type = type
local pcall = pcall
local select = select
local ipairs = ipairs
local assert = assert
local ngx_log = ngx.log
local ngx_WARN = ngx.WARN
local ngx_get_phase = ngx.get_phase


local _M = {
TYPE = {
BEFORE = 1,
AFTER = 2,
BEFORE_MUT = 3,
AFTER_MUT = 4,
},
}
local _M = {}


local NON_FUNCTION_HOOKS = {
Expand All @@ -37,7 +30,7 @@ local function should_execute_original_func(group_name)
if ALWAYS_ENABLED_GROUPS[group_name] then
return
end

local phase = ngx_get_phase()
if phase == "init" or phase == "init_worker" then
return true
Expand All @@ -58,7 +51,8 @@ end
local function execute_hook_vararg(hook, hook_type, group_name, ...)
if not hook then
return
end
end

local ok, err = pcall(hook, ...)
if not ok then
ngx_log(ngx_WARN, "failed to run ", hook_type, " hook of ", group_name, ": ", err)
Expand All @@ -70,14 +64,14 @@ local function execute_hooks_vararg(hooks, hook_type, group_name, ...)
if not hooks then
return
end

for _, hook in ipairs(hooks) do
execute_hook_vararg(hook, hook_type, group_name, ...)
end
end


local function execute_after_hooks_vararg(handlers, group_name, ...)
execute_hook_vararg(handlers.after_mut, "after_mut", group_name, ...)
execute_hooks_vararg(handlers.afters, "after", group_name, ...)
return ...
end
Expand All @@ -88,6 +82,7 @@ local function wrap_function_vararg(group_name, original_func, handlers)
if should_execute_original_func(group_name) then
return original_func(...)
end

execute_hooks_vararg(handlers.befores, "before", group_name, ...)
return execute_after_hooks_vararg(handlers, group_name, original_func(...))
end
Expand All @@ -98,6 +93,7 @@ local function execute_hook(hook, hook_type, group_name, a1, a2, a3, a4, a5, a6,
if not hook then
return
end

local ok, err = pcall(hook, a1, a2, a3, a4, a5, a6, a7, a8)
if not ok then
ngx_log(ngx_WARN, "failed to run ", hook_type, " hook of ", group_name, ": ", err)
Expand All @@ -109,6 +105,7 @@ local function execute_hooks(hooks, hook_type, group_name, a1, a2, a3, a4, a5, a
if not hooks then
return
end

for _, hook in ipairs(hooks) do
execute_hook(hook, hook_type, group_name, a1, a2, a3, a4, a5, a6, a7, a8)
end
Expand All @@ -132,48 +129,48 @@ local function execute_original_func(max_args, original_func, a1, a2, a3, a4, a5
return original_func(a1, a2, a3, a4, a5, a6)
elseif max_args == 7 then
return original_func(a1, a2, a3, a4, a5, a6, a7)
else
else
return original_func(a1, a2, a3, a4, a5, a6, a7, a8)
end
end


local function wrap_function(max_args, group_name, original_func, handlers)
return function(a1, a2, a3, a4, a5, a6, a7, a8)
local r1, r2, r3, r4, r5, r6, r7, r8

if should_execute_original_func(group_name) then
a1, a2, a3, a4, a5, a6, a7, a8 = execute_original_func(max_args, original_func, a1, a2, a3, a4, a5, a6, a7, a8)
r1, r2, r3, r4, r5, r6, r7, r8 = execute_original_func(max_args, original_func, a1, a2, a3, a4, a5, a6, a7, a8)

else
execute_hook(handlers.before_mut, "before_mut", group_name, a1, a2, a3, a4, a5, a6, a7, a8)
execute_hooks(handlers.befores, "before", group_name, a1, a2, a3, a4, a5, a6, a7, a8)
a1, a2, a3, a4, a5, a6, a7, a8 = execute_original_func(max_args, original_func, a1, a2, a3, a4, a5, a6, a7, a8)
execute_hook(handlers.after_mut, "after_mut", group_name, a1, a2, a3, a4, a5, a6, a7, a8)
execute_hooks(handlers.afters, "after", group_name, a1, a2, a3, a4, a5, a6, a7, a8)
r1, r2, r3, r4, r5, r6, r7, r8 = execute_original_func(max_args, original_func, a1, a2, a3, a4, a5, a6, a7, a8)
execute_hooks(handlers.afters, "after", group_name, r1, r2, r3, r4, r5, r6, r7, r8)
end
return a1, a2, a3, a4, a5, a6, a7, a8

return r1, r2, r3, r4, r5, r6, r7, r8
end
end


function _M.hook_function(group_name, parent, child_key, max_args, handlers)
function _M.hook_function(group_name, parent, function_key, max_args, handlers)
assert(type(group_name) == "string", "group_name must be a string")
assert(type(parent) == "table", "parent must be a table")
assert(type(child_key) == "string", "child_key must be a string")
assert(type(function_key) == "string", "function_key must be a string")

local is_varargs = max_args == "varargs"
if is_varargs then
assert(handlers.before_mut == nil, "before_mut is not supported for varargs functions")
else
if not is_varargs then
assert(type(max_args) == "number", 'max_args must be a number or "varargs"')
assert(max_args >= 0 and max_args <= 8, 'max_args must be >= 0 and <= 8, or "varargs"')
end

local original_func = parent[child_key]
assert(type(original_func) == "function", "parent[" .. child_key .. "] must be a function")
local original_func = parent[function_key]
assert(type(original_func) == "function", "parent[" .. function_key .. "] must be a function")

if is_varargs then
parent[child_key] = wrap_function_vararg(group_name, original_func, handlers)
parent[function_key] = wrap_function_vararg(group_name, original_func, handlers)
else
parent[child_key] = wrap_function(max_args, group_name, original_func, handlers)
parent[function_key] = wrap_function(max_args, group_name, original_func, handlers)
end
end

Expand All @@ -194,6 +191,8 @@ end


function _M.is_group_enabled(group_name)
assert(type(group_name) == "string", "group_name must be a string")

if ALWAYS_ENABLED_GROUPS[group_name] then
return true
end
Expand All @@ -212,7 +211,10 @@ function _M.is_group_enabled(group_name)
end


function _M.run_hooks(group_name, hook_name, a1, a2, a3, a4, a5, a6, a7, a8, ...)
function _M.run_hook(group_name, hook_name, a1, a2, a3, a4, a5, a6, a7, a8, ...)
assert(type(group_name) == "string", "group_name must be a string")
assert(type(hook_name) == "string", "hook_name must be a string")

if not _M.is_group_enabled(group_name) then
return
end
Expand All @@ -234,13 +236,16 @@ function _M.run_hooks(group_name, hook_name, a1, a2, a3, a4, a5, a6, a7, a8, ...
else
ok, err = pcall(handler, a1, a2, a3, a4, a5, a6, a7, a8, ...)
end

if not ok then
ngx_log(ngx_WARN, "failed to run dynamic hook ", group_name, ".", hook_name, ": ", err)
end
end


function _M.enable_on_this_request(group_name, ngx_ctx)
assert(type(group_name) == "string", "group_name must be a string")

ngx_ctx = ngx_ctx or ngx.ctx
if ngx_ctx.dynamic_hook then
ngx_ctx.dynamic_hook.enabled_groups[group_name] = true
Expand All @@ -255,6 +260,8 @@ end


function _M.always_enable(group_name)
assert(type(group_name) == "string", "group_name must be a string")

ALWAYS_ENABLED_GROUPS[group_name] = true
end

Expand Down
Loading
Loading