chore(emqx_machine): refactor injecting runtime deps
Co-authored-by: Thales Macedo Garitezi <thalesmg@gmail.com>
This commit is contained in:
parent
db3f285054
commit
6a092aeb69
|
@ -166,9 +166,8 @@ is_app(Name) ->
|
|||
sorted_reboot_apps() ->
|
||||
RebootApps = reboot_apps(),
|
||||
Apps0 = [{App, app_deps(App, RebootApps)} || App <- RebootApps],
|
||||
Apps1 = inject_bridge_deps(Apps0),
|
||||
Apps2 = inject_dashboard_deps(Apps1),
|
||||
sorted_reboot_apps(Apps2).
|
||||
Apps = emqx_machine_boot_runtime_deps:inject(Apps0, runtime_deps()),
|
||||
sorted_reboot_apps(Apps).
|
||||
|
||||
app_deps(App, RebootApps) ->
|
||||
case application:get_key(App, applications) of
|
||||
|
@ -176,43 +175,21 @@ app_deps(App, RebootApps) ->
|
|||
{ok, List} -> lists:filter(fun(A) -> lists:member(A, RebootApps) end, List)
|
||||
end.
|
||||
|
||||
%% `emqx_bridge' is special in that it needs all the bridges apps to
|
||||
%% be started before it, so that, when it loads the bridges from
|
||||
%% configuration, the bridge app and its dependencies need to be up.
|
||||
%%
|
||||
%% `emqx_connector' also needs to start all connector dependencies for the same reason.
|
||||
%% Since standalone apps like `emqx_mongodb' are already dependencies of `emqx_bridge_*'
|
||||
%% apps, we may apply the same tactic for `emqx_connector' and inject individual bridges
|
||||
%% as its dependencies.
|
||||
inject_bridge_deps(RebootAppDeps) ->
|
||||
BridgeApps = [
|
||||
App
|
||||
|| {App, _Deps} <- RebootAppDeps,
|
||||
lists:prefix("emqx_bridge_", atom_to_list(App))
|
||||
],
|
||||
lists:map(
|
||||
fun
|
||||
({emqx_bridge, Deps0}) when is_list(Deps0) ->
|
||||
{emqx_bridge, Deps0 ++ BridgeApps};
|
||||
({emqx_connector, Deps0}) when is_list(Deps0) ->
|
||||
{emqx_connector, Deps0 ++ BridgeApps};
|
||||
(App) ->
|
||||
App
|
||||
end,
|
||||
RebootAppDeps
|
||||
).
|
||||
inject_dashboard_deps(Reboots) ->
|
||||
Apps = [emqx_license],
|
||||
Deps = lists:filter(fun(App) -> lists:keymember(App, 1, Reboots) end, Apps),
|
||||
lists:map(
|
||||
fun
|
||||
({emqx_dashboard, Deps0}) when is_list(Deps0) ->
|
||||
{emqx_dashboard, Deps0 ++ Deps};
|
||||
(App) ->
|
||||
App
|
||||
end,
|
||||
Reboots
|
||||
).
|
||||
runtime_deps() ->
|
||||
[
|
||||
%% `emqx_bridge' is special in that it needs all the bridges apps to
|
||||
%% be started before it, so that, when it loads the bridges from
|
||||
%% configuration, the bridge app and its dependencies need to be up.
|
||||
{emqx_bridge, fun(App) -> lists:prefix("emqx_bridge_", atom_to_list(App)) end},
|
||||
%% `emqx_connector' also needs to start all connector dependencies for the same reason.
|
||||
%% Since standalone apps like `emqx_mongodb' are already dependencies of `emqx_bridge_*'
|
||||
%% apps, we may apply the same tactic for `emqx_connector' and inject individual bridges
|
||||
%% as its dependencies.
|
||||
{emqx_connector, fun(App) -> lists:prefix("emqx_bridge_", atom_to_list(App)) end},
|
||||
%% emqx_fdb is an EE app
|
||||
{emqx_durable_storage, emqx_fdb},
|
||||
{emqx_dashboard, emqx_license}
|
||||
].
|
||||
|
||||
sorted_reboot_apps(Apps) ->
|
||||
G = digraph:new(),
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
%%--------------------------------------------------------------------
|
||||
%% Copyright (c) 2024 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||
%%
|
||||
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||
%% you may not use this file except in compliance with the License.
|
||||
%% You may obtain a copy of the License at
|
||||
%%
|
||||
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||
%%
|
||||
%% Unless required by applicable law or agreed to in writing, software
|
||||
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
%% See the License for the specific language governing permissions and
|
||||
%% limitations under the License.
|
||||
%%--------------------------------------------------------------------
|
||||
-module(emqx_machine_boot_runtime_deps).
|
||||
|
||||
-export([inject/2]).
|
||||
|
||||
-type app_name() :: atom().
|
||||
-type app_deps() :: {app_name(), [app_name()]}.
|
||||
-type app_selector() :: app_name() | fun((app_name()) -> boolean()).
|
||||
-type runtime_dep() :: {_WhatDepends :: app_name(), _OnWhat :: app_selector()}.
|
||||
|
||||
-spec inject([app_deps()], [runtime_dep()]) -> [app_deps()].
|
||||
inject(AppDepList, DepSpecs) ->
|
||||
AppDep0 = maps:from_list(AppDepList),
|
||||
AppDep1 = lists:foldl(
|
||||
fun(DepSpec, AppDepAcc) ->
|
||||
inject_one_dep(AppDepAcc, DepSpec)
|
||||
end,
|
||||
AppDep0,
|
||||
DepSpecs
|
||||
),
|
||||
maps:to_list(AppDep1).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Internal functions
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
inject_one_dep(AppDep, {WhatDepends, OnWhatSelector}) ->
|
||||
OnWhat = select_apps(OnWhatSelector, maps:keys(AppDep)),
|
||||
case AppDep of
|
||||
#{WhatDepends := Deps} when is_list(Deps) ->
|
||||
AppDep#{WhatDepends => lists:usort(Deps ++ OnWhat)};
|
||||
_ ->
|
||||
AppDep
|
||||
end.
|
||||
|
||||
select_apps(AppName, AppNames) when is_atom(AppName) ->
|
||||
lists:filter(fun(App) -> App =:= AppName end, AppNames);
|
||||
select_apps(AppSelector, AppNames) when is_function(AppSelector, 1) ->
|
||||
lists:filter(AppSelector, AppNames).
|
Loading…
Reference in New Issue