feat: don't dispatch requests until dispatch is ready

This commit is contained in:
Zhongwen Deng 2022-05-07 16:48:03 +08:00
parent b91e9e59ba
commit 068421d0e1
4 changed files with 44 additions and 23 deletions

View File

@ -27,9 +27,6 @@
all_ciphers/0 all_ciphers/0
]). ]).
-compile(export_all).
-compile(nowarn_export_all).
%% SSL files %% SSL files
-export([ -export([
ensure_ssl_files/2, ensure_ssl_files/2,
@ -219,19 +216,18 @@ default_versions(_) ->
%% Deduplicate a list without re-ordering the elements. %% Deduplicate a list without re-ordering the elements.
dedup([]) -> dedup([]) ->
[]; [];
dedup(List) -> dedup(List0) ->
lists:reverse( List = lists:foldl(
lists:foldl( fun(L, Acc) ->
fun(L, Acc) -> case lists:member(L, Acc) of
case lists:member(L, Acc) of false -> [L | Acc];
false -> [L | Acc]; true -> Acc
true -> Acc end
end end,
end, [],
[], List0
List ),
) lists:reverse(List).
).
%% parse comma separated tls version strings %% parse comma separated tls version strings
parse_versions(Versions) -> parse_versions(Versions) ->

View File

@ -81,7 +81,7 @@ start_listeners(Listeners) ->
security => [#{'basicAuth' => []}, #{'bearerAuth' => []}], security => [#{'basicAuth' => []}, #{'bearerAuth' => []}],
swagger_global_spec => GlobalSpec, swagger_global_spec => GlobalSpec,
dispatch => Dispatch, dispatch => Dispatch,
middlewares => [cowboy_router, ?EMQX_MIDDLE, cowboy_handler] middlewares => [?EMQX_MIDDLE, cowboy_router, cowboy_handler]
}, },
Res = Res =
lists:foldl( lists:foldl(

View File

@ -25,7 +25,7 @@
-behaviour(gen_server). -behaviour(gen_server).
-export([start_link/0]). -export([start_link/0, is_ready/0]).
-export([ -export([
init/1, init/1,
@ -37,29 +37,34 @@
code_change/3 code_change/3
]). ]).
is_ready() ->
ready =:= gen_server:call(?MODULE, get_state, 10000).
start_link() -> start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
init([]) -> init([]) ->
erlang:process_flag(trap_exit, true), erlang:process_flag(trap_exit, true),
ok = add_handler(), ok = add_handler(),
{ok, #{}, {continue, regenerate_dispatch}}. {ok, undefined, {continue, regenerate_dispatch}}.
handle_continue(regenerate_dispatch, State) -> handle_continue(regenerate_dispatch, _State) ->
regenerate_minirest_dispatch(), regenerate_minirest_dispatch(),
{noreply, State, hibernate}. {noreply, ready, hibernate}.
handle_call(get_state, _From, State) ->
{reply, State, State, hibernate};
handle_call(_Request, _From, State) -> handle_call(_Request, _From, State) ->
{reply, ok, State, hibernate}. {reply, ok, State, hibernate}.
handle_cast(_Request, State) -> handle_cast(_Request, State) ->
{noreply, State, hibernate}. {noreply, State, hibernate}.
handle_info({update_listeners, OldListeners, NewListeners}, State) -> handle_info({update_listeners, OldListeners, NewListeners}, _State) ->
ok = emqx_dashboard:stop_listeners(OldListeners), ok = emqx_dashboard:stop_listeners(OldListeners),
ok = emqx_dashboard:start_listeners(NewListeners), ok = emqx_dashboard:start_listeners(NewListeners),
regenerate_minirest_dispatch(), regenerate_minirest_dispatch(),
{noreply, State, hibernate}; {noreply, ready, hibernate};
handle_info(_Info, State) -> handle_info(_Info, State) ->
{noreply, State, hibernate}. {noreply, State, hibernate}.

View File

@ -21,6 +21,7 @@
-export([execute/2]). -export([execute/2]).
execute(Req, Env) -> execute(Req, Env) ->
waiting_dispatch_ready(),
CORS = emqx_conf:get([dashboard, cors], false), CORS = emqx_conf:get([dashboard, cors], false),
case CORS andalso cowboy_req:header(<<"origin">>, Req, undefined) of case CORS andalso cowboy_req:header(<<"origin">>, Req, undefined) of
false -> false ->
@ -31,3 +32,22 @@ execute(Req, Env) ->
Req2 = cowboy_req:set_resp_header(<<"Access-Control-Allow-Origin">>, <<"*">>, Req), Req2 = cowboy_req:set_resp_header(<<"Access-Control-Allow-Origin">>, <<"*">>, Req),
{ok, Req2, Env} {ok, Req2, Env}
end. end.
waiting_dispatch_ready() ->
waiting_dispatch_ready(5).
waiting_dispatch_ready(0) ->
ok;
waiting_dispatch_ready(Count) ->
case emqx_sys:uptime() < timer:minutes(1) of
true ->
case emqx_dashboard_listener:is_ready() of
true ->
ok;
false ->
timer:sleep(100),
waiting_dispatch_ready(Count - 1)
end;
false ->
ok
end.