Erlang: когда выполнять `inets:start()`?
Какое место подходит для выполнения inets:start()
?
- в модуле `applicationname_app'?
- в
applicationname_sup
модуль супервизора? - в дочернем процессе висит от супервизора?\
- где-нибудь еще?
(Я все еще борюсь с inets:httpd
)
Примечание: ответ не может быть на мелодию "используйте загрузочный файл", пожалуйста.
1 ответ
inets - это автономное Erlang-приложение; inets:start()
это просто псевдоним application:start(inets)
, Я думаю, что ответ во многом зависит от того, как вы поддерживаете свой код.
Если ваш код упакован как приложение, ваш файл.app должен отображаться inets
как требуется, чтобы быть запущенным до вашего (см. тег приложения). Начиная ваше заявление с application:start(my_app).
Теперь убедитесь, что inets также запущен. Следствие: если вы создадите загрузочный файл, он также запустит инет для вас:-P
Если вы заинтересованы в том, чтобы не использовать приложения, я думаю, что выбор зависит от того, как работает ваш код. Если вам всегда будут нужны инеты для запуска, лучше начать с любого из ваших руководителей. Если это редко требуется, вы всегда можете убедиться, что он запускается с чем-то вроде:
ensure_app_started(App) ->
case application:started(App) of
ok -> ok;
{error, already_started} -> ok;
Error -> Error
end.
В 2019 году мы используем rebar3
для создания приложения и управления его зависимостями. Для зависимостей, которые необходимо загрузить, вы добавляете их вrebar.config
, а также rebar3
загрузит зависимости. Например, если вы добавитеhackney
(http-клиент) в rebar.config:
{erl_opts, [debug_info]}.
{deps, [
{hackney, ".*", {git, "git://github.com/benoitc/hackney.git", {branch, "master"}}}
]}.
{shell, [
% {config, "config/sys.config"},
{apps, [http_client]}
]}.
Затем сделайте:
../your_app_name$ rebar3 compile
rebar3
скачает hackney
и скомпилируйте все файлы в application
.
Чтобы убедиться, что все ваши зависимости запускаются раньше вашего приложения, вы добавляете имена зависимостей в:
src/your_app_name.app.src
Например,
{application, http_client,
[{description, "An OTP application"},
{vsn, "0.1.0"},
{registered, []},
{mod, {http_client_app, []}},
{applications,
[kernel,
stdlib,
hackney %%%<=========HERE
]},
{env,[]},
{modules, []},
{licenses, ["Apache 2.0"]},
{links, []}
]}.
Фактический файл.app создается здесь:
_build/default/lib/your_app_name/ebin/your_app_name.app
Чтобы запустить приложение в оболочке вместе со всеми его зависимостями, выполните:
../your_app_name$ rebar3 shell
В inets
приложение поставляется с erlang, поэтому его не нужно загружать, поэтому вы не указываете inets как зависимость в rebar.config (вы получите сообщение об ошибке, когда $ rebar3 compile
). Вам все еще нужно указать inets как зависимость в вашемapplication
в файле:
src/your_app_name.app.src
Но rebar3
сам использует inets
(чтобы загрузить ваши зависимости), поэтому, даже если вы не указали inets
как зависимость в вашем приложении, inets
все равно начнется раньше, чем ваше приложение. Вы можете проверить это, не указавinets
как зависимость в вашем application
, затем выполните:
$ rebar3 shell
...
...
1> application:start(inets)
{error,{already_started,inets}}
Но не полагайтесь на это и НЕ УКАЗЫВАЙТЕ inets
как зависимость в вашем приложении.
Если ваш код упакован как приложение, укажитеinets
в файле ресурсов приложения:
% Filename: ebin/flamingo.app
{application, flamingo,
[{vsn, "1.0.0"},
{modules, [flamingo_app,
flamingo_sup,
flamingo]},
{applications, [kernel,
stdlib,
inets]},
{mod, {flamingo_app, []}}
]}.
Затем вы можете запустить приложение, используя application:ensure_all_started(flamingo)
. Это гарантирует, что inets запускается автоматически для вас (т.е. нет необходимости явно вызыватьinets:start()
).
Например (при условии, что файлы *.app и *.beam находятся в ebin/
):
$ erl -pa ebin/
Eshell V9.2 (abort with ^G)
1> application:ensure_all_started(flamingo).
{ok,[inets,flamingo]}