refactor(exhook): load only the necessary hooks
This commit is contained in:
parent
4585306774
commit
0d8c137cb5
|
@ -22,6 +22,8 @@
|
||||||
|
|
||||||
-emqx_plugin(extension).
|
-emqx_plugin(extension).
|
||||||
|
|
||||||
|
-define(REGISTRAY, emqx_exhook_registray).
|
||||||
|
|
||||||
-export([ start/2
|
-export([ start/2
|
||||||
, stop/1
|
, stop/1
|
||||||
, prep_stop/1
|
, prep_stop/1
|
||||||
|
@ -30,8 +32,8 @@
|
||||||
%% Internal export
|
%% Internal export
|
||||||
-export([ load_server/2
|
-export([ load_server/2
|
||||||
, unload_server/1
|
, unload_server/1
|
||||||
, load_exhooks/0
|
|
||||||
, unload_exhooks/0
|
, unload_exhooks/0
|
||||||
|
, init_hook_registray/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
@ -41,12 +43,12 @@
|
||||||
start(_StartType, _StartArgs) ->
|
start(_StartType, _StartArgs) ->
|
||||||
{ok, Sup} = emqx_exhook_sup:start_link(),
|
{ok, Sup} = emqx_exhook_sup:start_link(),
|
||||||
|
|
||||||
|
%% Collect all available hooks
|
||||||
|
_ = init_hook_registray(),
|
||||||
|
|
||||||
%% Load all dirvers
|
%% Load all dirvers
|
||||||
load_all_servers(),
|
load_all_servers(),
|
||||||
|
|
||||||
%% Register all hooks
|
|
||||||
_ = load_exhooks(),
|
|
||||||
|
|
||||||
%% Register CLI
|
%% Register CLI
|
||||||
emqx_ctl:register_command(exhook, {emqx_exhook_cli, cli}, []),
|
emqx_ctl:register_command(exhook, {emqx_exhook_cli, cli}, []),
|
||||||
{ok, Sup}.
|
{ok, Sup}.
|
||||||
|
@ -81,11 +83,14 @@ unload_server(Name) ->
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Exhooks
|
%% Exhooks
|
||||||
|
|
||||||
load_exhooks() ->
|
init_hook_registray() ->
|
||||||
[emqx:hook(Name, {M, F, A}) || {Name, {M, F, A}} <- search_exhooks()].
|
_ = ets:new(?REGISTRAY, [public, named_table]),
|
||||||
|
[ets:insert(?REGISTRAY, {Name, {M, F, A}, 0})
|
||||||
|
|| {Name, {M, F, A}} <- search_exhooks()].
|
||||||
|
|
||||||
unload_exhooks() ->
|
unload_exhooks() ->
|
||||||
[emqx:unhook(Name, {M, F}) || {Name, {M, F, _A}} <- search_exhooks()].
|
[emqx:unhook(Name, {M, F}) ||
|
||||||
|
{Name, {M, F, _A}, _} <- ets:tab2list(?REGISTRAY)].
|
||||||
|
|
||||||
search_exhooks() ->
|
search_exhooks() ->
|
||||||
search_exhooks(ignore_lib_apps(application:loaded_applications())).
|
search_exhooks(ignore_lib_apps(application:loaded_applications())).
|
||||||
|
|
|
@ -307,8 +307,26 @@ stringfy(Term) when is_atom(Term) ->
|
||||||
stringfy(Term) ->
|
stringfy(Term) ->
|
||||||
unicode:characters_to_binary((io_lib:format("~0p", [Term]))).
|
unicode:characters_to_binary((io_lib:format("~0p", [Term]))).
|
||||||
|
|
||||||
hexstr(B) ->
|
hexstr(<<>>) -> [];
|
||||||
iolist_to_binary([io_lib:format("~2.16.0B", [X]) || X <- binary_to_list(B)]).
|
hexstr(<<H:4, L:4, B/binary>>) ->
|
||||||
|
iolist_to_binary([hexchar(H), hexchar(L)] ++ hexstr(B)).
|
||||||
|
|
||||||
|
hexchar(0) -> $0;
|
||||||
|
hexchar(1) -> $1;
|
||||||
|
hexchar(2) -> $2;
|
||||||
|
hexchar(3) -> $3;
|
||||||
|
hexchar(4) -> $4;
|
||||||
|
hexchar(5) -> $5;
|
||||||
|
hexchar(6) -> $6;
|
||||||
|
hexchar(7) -> $7;
|
||||||
|
hexchar(8) -> $8;
|
||||||
|
hexchar(9) -> $9;
|
||||||
|
hexchar(10) -> $A;
|
||||||
|
hexchar(11) -> $B;
|
||||||
|
hexchar(12) -> $C;
|
||||||
|
hexchar(13) -> $D;
|
||||||
|
hexchar(14) -> $E;
|
||||||
|
hexchar(15) -> $F.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Acc funcs
|
%% Acc funcs
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
-logger_header("[ExHook Svr]").
|
-logger_header("[ExHook Svr]").
|
||||||
|
|
||||||
|
-define(REGISTRAY, emqx_exhook_registray).
|
||||||
-define(PB_CLIENT_MOD, emqx_exhook_v_1_hook_provider_client).
|
-define(PB_CLIENT_MOD, emqx_exhook_v_1_hook_provider_client).
|
||||||
|
|
||||||
%% Load/Unload
|
%% Load/Unload
|
||||||
|
@ -83,13 +84,19 @@
|
||||||
load(Name0, Opts0) ->
|
load(Name0, Opts0) ->
|
||||||
Name = prefix(Name0),
|
Name = prefix(Name0),
|
||||||
{SvrAddr, ClientOpts} = channel_opts(Opts0),
|
{SvrAddr, ClientOpts} = channel_opts(Opts0),
|
||||||
case emqx_exhook_sup:start_grpc_client_channel(Name, SvrAddr, ClientOpts) of
|
case emqx_exhook_sup:start_grpc_client_channel(
|
||||||
|
Name,
|
||||||
|
SvrAddr,
|
||||||
|
ClientOpts) of
|
||||||
{ok, _ChannPoolPid} ->
|
{ok, _ChannPoolPid} ->
|
||||||
case do_init(Name) of
|
case do_init(Name) of
|
||||||
{ok, HookSpecs} ->
|
{ok, HookSpecs} ->
|
||||||
%% Reigster metrics
|
%% Reigster metrics
|
||||||
Prefix = lists:flatten(io_lib:format("exhook.~s.", [Name])),
|
Prefix = lists:flatten(
|
||||||
|
io_lib:format("exhook.~s.", [Name])),
|
||||||
ensure_metrics(Prefix, HookSpecs),
|
ensure_metrics(Prefix, HookSpecs),
|
||||||
|
%% Ensure hooks
|
||||||
|
ensure_hooks(HookSpecs),
|
||||||
{ok, #server{name = Name,
|
{ok, #server{name = Name,
|
||||||
options = Opts0,
|
options = Opts0,
|
||||||
channel = _ChannPoolPid,
|
channel = _ChannPoolPid,
|
||||||
|
@ -126,8 +133,9 @@ channel_opts(Opts) ->
|
||||||
{SvrAddr, ClientOpts}.
|
{SvrAddr, ClientOpts}.
|
||||||
|
|
||||||
-spec unload(server()) -> ok.
|
-spec unload(server()) -> ok.
|
||||||
unload(#server{name = Name}) ->
|
unload(#server{name = Name, hookspec = HookSpecs}) ->
|
||||||
_ = do_deinit(Name),
|
_ = do_deinit(Name),
|
||||||
|
_ = may_unload_hooks(HookSpecs),
|
||||||
_ = emqx_exhook_sup:stop_grpc_client_channel(Name),
|
_ = emqx_exhook_sup:stop_grpc_client_channel(Name),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
@ -177,6 +185,31 @@ ensure_metrics(Prefix, HookSpecs) ->
|
||||||
|| Hookpoint <- maps:keys(HookSpecs)],
|
|| Hookpoint <- maps:keys(HookSpecs)],
|
||||||
lists:foreach(fun emqx_metrics:ensure/1, Keys).
|
lists:foreach(fun emqx_metrics:ensure/1, Keys).
|
||||||
|
|
||||||
|
ensure_hooks(HookSpecs) ->
|
||||||
|
lists:foreach(fun(Hookpoint) ->
|
||||||
|
case ets:lookup(?REGISTRAY, Hookpoint) of
|
||||||
|
[] ->
|
||||||
|
?LOG(warning, "Hoook ~s not found in registray", [Hookpoint]);
|
||||||
|
[{Hookpoint, {M, F, A}, _}] ->
|
||||||
|
emqx_hooks:put(Hookpoint, {M, F, A}),
|
||||||
|
ets:update_counter(?REGISTRAY, Hookpoint, {3, 1})
|
||||||
|
end
|
||||||
|
end, maps:keys(HookSpecs)).
|
||||||
|
|
||||||
|
may_unload_hooks(HookSpecs) ->
|
||||||
|
lists:foreach(fun(Hookpoint) ->
|
||||||
|
case ets:update_counter(?REGISTRAY, Hookpoint, {3, -1}) of
|
||||||
|
Cnt when Cnt =< 0 ->
|
||||||
|
case ets:lookup(?REGISTRAY, Hookpoint) of
|
||||||
|
[{Hookpoint, {M, F, _A}, _}] ->
|
||||||
|
emqx_hooks:del(Hookpoint, {M, F});
|
||||||
|
_ -> ok
|
||||||
|
end,
|
||||||
|
ets:delete(?REGISTRAY, Hookpoint);
|
||||||
|
_ -> ok
|
||||||
|
end
|
||||||
|
end, maps:keys(HookSpecs)).
|
||||||
|
|
||||||
format(#server{name = Name, hookspec = Hooks}) ->
|
format(#server{name = Name, hookspec = Hooks}) ->
|
||||||
io_lib:format("name=~p, hooks=~0p", [Name, Hooks]).
|
io_lib:format("name=~p, hooks=~0p", [Name, Hooks]).
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue