Erlang,如何加载应用程序及其依赖项



我的集群中有一些应用程序,有时我需要在不同的主机上启动其中一些应用程序。

故事是 Erlang 集群已经在运行,所以即使我为每个应用程序都有我的.app资源文件,说明哪些应用程序应该在我的应用程序之前启动,但这仅适用于创建启动脚本,而不是在已经运行的节点中启动应用程序。

目前我有一个自定义例程,它使用 application:get_key(Application,applications) 提取依赖项并在启动给定应用程序之前单独启动它们。

我想知道是否有更好的方法可以做到这一点。

从 Erlang R16B02 开始,也有application:ensure_all_started .

坦率地说,在 Erlang 中执行此操作的标准工具现在不必要地烦人。我倾向于将以下样板放在我的应用程序回调模块中:

-module(myapp_app).
-export([start/0]).
start() -> a_start(myapp, permanent).
a_start(App, Type) ->
    start_ok(App, Type, application:start(App, Type)).
start_ok(_App, _Type, ok) -> ok;
start_ok(_App, _Type, {error, {already_started, _App}}) -> ok;
start_ok(App, Type, {error, {not_started, Dep}}) ->
    ok = a_start(Dep, Type),
    a_start(App, Type);
start_ok(App, _Type, {error, Reason}) ->
    erlang:error({app_start_failed, App, Reason}).

然后,您可以将-s myapp_app添加到 erlang 命令行,这将递归启动应用程序及其所有依赖项。为什么这个函数不在应用程序模块中

,我不知道:)

在我的 Erlang Factory 2012 SFBay 示例应用程序中有一个此自定义 erlang 应用程序启动代码的工作示例。

在启动脚本之外启动应用时,确实需要先启动依赖项。您可以构建智能以在应用程序本身中执行此操作,以便在应用程序启动时,它将在需要之前启动任何所需的依赖项。

我看到这样做的一个地方是在Mochiweb应用程序中。默认应用模板包括用于在启动时加载依赖项的代码:

-module(some_app).
-export([start/0, stop/0]).
ensure_started(App) ->
    case application:start(App) of
        ok ->
            ok;
        {error, {already_started, App}} ->
            ok
    end.
%% @spec start() -> ok
%% @doc Start the some_app server.
start() ->
    some_app_deps:ensure(),
    ensure_started(crypto),
    application:start(some_app).
%% @spec stop() -> ok
%% @doc Stop the some_app server.
stop() ->
    application:stop(some_app).

如果您在"OTP 设计原则"下编写应用程序,则必须创建 yourappname.app 文件,其中包含"应用程序"部分。本节定义要在启动之前启动哪些其他应用程序。这里说明:

应用

在此之前必须启动的所有应用程序应用程序已启动。系统工具使用此列表生成正确的引导脚本。默认为 [],但请注意,所有应用程序都具有至少依赖于内核和 stdlib。

因此,如果您使用版本,则此依赖项解析将由 systools 解决。

最新更新