Erlang, как загружать приложения с их зависимостями

У меня есть несколько приложений в моем кластере, мне нужно запускать некоторые из них иногда на разных хостах.

Дело в том, что кластер Erlang уже запущен, поэтому, хотя у меня есть файл ресурсов.app для каждого приложения, в котором указано, какие приложения должны быть запущены до моего, это работает только для создания сценария запуска, а не для запуска приложения в уже запущенном приложении. узел.

На данный момент у меня есть пользовательская подпрограмма, которая использует application:get_key(Приложение, приложения), чтобы извлечь зависимости и запустить их отдельно перед запуском данного приложения.

Мне было интересно, если нет лучшего способа сделать это.

4 ответа

Решение

При запуске приложения вне сценария запуска вам нужно сначала запустить зависимости. Вы можете встроить смарт-коды, чтобы сделать это в самом приложении, чтобы при запуске приложения оно запускало все необходимые зависимости до того, как оно им понадобится.

Одно из мест, где я видел это, - приложения 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).

Поскольку 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.

Если вы пишете свое приложение в разделе "Принципы разработки OTP", вам придется создать файл yourappname.app, который будет содержать раздел "Приложения". Этот раздел определяет, какие другие приложения вы хотите запускать раньше, чем ваши. Здесь говорится:

Приложения

Все приложения, которые должны быть запущены до запуска этого приложения. systools использует этот список для генерации правильных загрузочных скриптов. По умолчанию [], но обратите внимание, что все приложения имеют зависимости как минимум от ядра и stdlib.

Поэтому, если вы используете релизы, это разрешение зависимостей будет решаться с помощью systools.

Другие вопросы по тегам