Как настроить профили httpc с помощью rebar3?

Как установить параметры конфигурации для профилей http://erlang.org/doc/man/httpc.html при использовании rebar3?

Вот единственный пример через erl -config inets.config это выглядит так:

[{inets, 
[{services,[{httpc,[{profile, server1}]},
            {httpc, [{profile, server2}]}]}]
}].

Я попытался адаптировать его к своей структуре проекта rebar3.

Код

Проект был создан с помощью rebar3, со стандартной компоновкой OTP:

rebar3 new release myapp

Вот мой myapp/config/sys.config:

[
  { myapp, []},
  {inets, [{services, [{httpc, [{profile, myapp}]}]}]}
].

rebar.config:

{erl_opts, [debug_info]}.
{deps, []}.

{relx, [{release, { myapp, "0.1.0" },
         [myapp,
          sasl]},

        {sys_config, "./config/sys.config"},
        {vm_args, "./config/vm.args"},

        {dev_mode, true},
        {include_erts, false},

        {extended_start_script, true}]
}.

{profiles, [{prod, [{relx, [{dev_mode, false},
                            {include_erts, true}]}]
            }]
}.

Вот мой файл myapp.app.src для полноты картины:

{application, myapp,
 [{description, "An OTP application"},
  {vsn, "0.1.0"},
  {registered, []},
  {mod, { myapp_app, []}},
  {applications,
   [kernel,
    stdlib
   ]},
  {env,[]},
  {modules, []},

  {maintainers, []},
  {licenses, []},
  {links, []}
 ]}.

Запросы

Вот запрос, который я пытаюсь сделать из оболочки арматуры:

$ ./rebar3 shell
1> ===> Booted myapp
1> ===> Booted sasl
...
1> httpc:request( "http://reddit.com", myapp).
** exception exit: {noproc,
                    {gen_server,call,
                     [httpc_myapp,
                      {request,
                       {request,undefined,<0.88.0>,0,http,
                        {"reddit.com",80},
                        "/",[],get,
                        {http_request_h,undefined,"keep-alive",undefined,
                         undefined,undefined,undefined,undefined,undefined,
                         undefined,...},
                        {[],[]},
                        {http_options,"HTTP/1.1",infinity,true,
                         {essl,[]},
                         undefined,false,infinity,...},
                        "http://reddit.com",[],none,[],1478280329839,
                        undefined,undefined,false}},
                      infinity]}}
     in function  gen_server:call/3 (gen_server.erl, line 212)
     in call from httpc:handle_request/9 (httpc.erl, line 574)

Вот запрос без профиля, чтобы проверить, действительно ли работает inets:

2> httpc:request( "http://reddit.com").

=PROGRESS REPORT==== 4-Nov-2016::13:25:51 ===
          supervisor: {local,inet_gethost_native_sup}
             started: [{pid,<0.107.0>},{mfa,{inet_gethost_native,init,[[]]}}]

=PROGRESS REPORT==== 4-Nov-2016::13:25:51 ===
          supervisor: {local,kernel_safe_sup}
             started: [{pid,<0.106.0>},
                       {id,inet_gethost_native_sup},
                       {mfargs,{inet_gethost_native,start_link,[]}},
                       {restart_type,temporary},
                       {shutdown,1000},
                       {child_type,worker}]
{ok,{{"HTTP/1.1",200,"OK"},...

person Andriy Drozdyuk    schedule 27.10.2016    source источник
comment
пожалуйста, покажи свой rebar.config.   -  person reith    schedule 04.11.2016


Ответы (2)


Сам rebar3 использует HTTP-клиенты inets, поэтому, когда он запускает ваше приложение в оболочке, inets уже запущен и настроен. Одним из обходных путей может быть остановка inets до запуска вашего приложения, как это предложено разработчиком rebar3 (скопировано ниже ). Другим будет загрузка вашего релиза в консольном режиме:

./_build/default/rel/myapp/bin/myapp console

Кроме того, есть еще одна проблема с вашим проектом. Вы не сказали, что хотите, чтобы для вас запускались инеты. У вас должна быть эта строка в myapp.src:

{applications, [kernel, stdlib, inets]}

Или вы можете указать inets в разделе выпуска rebar.config, чтобы сообщить relx, что это приложение должно быть включено в выпуск и запускаться при загрузке.

{relx, [{release, { myapp, "0.1.0" }, [inets, myapp, sasl]} ]}

Остановить загрузку Inets при запуске оболочки rebar3

Вот копия полного ответа Фреда Хеберта из списка рассылки rebar3:

Нам нужны inets для получения пакетов, и, скорее всего, мы не отключим их автоматически для всех случаев использования, так как это может поставить под угрозу общее использование агента rebar3 в случае, когда пользовательское приложение не использует inets, но по-прежнему запрашивает получение пакетов при последующем запуске. . Обходной путь, который я бы предложил, состоял в том, чтобы использовать для этого сценарий ловушки. Хуки-скрипты запускаются перед загрузкой пользовательских приложений и являются обычными эскриптами:

#!/usr/bin/env escript 
main(_) -> application:stop(inets). 

Затем вы можете подключить скрипт с помощью:

{shell, [{script_file, "path/to/file"}]} 

в rebar3.config или с помощью

rebar3 shell --script_file test/check_env.escript
person reith    schedule 05.11.2016
comment
Спасибо. Вы были правы насчет автоматического запуска inets вместе с оболочкой rebar3! Выполнение небольшого трюка в ссылке помогло. - person Andriy Drozdyuk; 07.11.2016

Я не могу найти в документации ничего, чтобы предположить, что rebar.config может содержать нужную вам конфигурацию приложения.

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

Если вы используете rebar3 для выпуска и запускаете службу с помощью скрипт, созданный с помощью relx (по умолчанию из _build/default/rel/<release_name>/bin/<release_name>) файл конфигурации приложения передается в erl для вас . Если файл конфигурации существует в каталоге вашего приложения, по умолчанию в config/sys.config, он будет рассматриваться как конфигурация приложения, в противном случае будет создана пустая конфигурация. Вы можете настроить его путь с помощью параметра выпуска sys_config.

Для нашего программного обеспечения у нас обычно был один файл config/sys.config. Структура аналогична предоставленному вами образцу конфигурации. Обратите внимание, что файл конфигурации может содержать настройки для многих различных служб. Например, смешав inets с одним из наших:

[{inets, [
     {services,[{httpc,[{profile, server1}]},
     {httpc, [{profile, server2}]}]}
 ]},
 {my_app, [
     {my_setting, "my value"}
 ]}
].

Запускаем с erl -config config/sys.config. Таким образом, если нам нужно установить конфигурацию службы, мы можем просто обновить наш файл конфигурации, в котором также содержится конфигурация, специфичная для этого приложения.

Насколько я знаю, это правильный метод для использования. Я не смог найти документацию, подтверждающую какой-либо другой способ сделать это.

person Andrakis    schedule 03.11.2016
comment
Не знаю, кто минусовал это. Извини друг. Спасибо за предложение, но это не совсем то, что я ищу. - person Andriy Drozdyuk; 03.11.2016
comment
Рейт расширил ответ. Может, сейчас это больше выручает? (Спасибо, Рейт!) - person Andrakis; 04.11.2016
comment
Все еще не работает. Я получаю noproc, когда пытаюсь создать httpc:request с профилем myapp. Я также попробовал автономную запись httpc, как вы предложили. - person Andriy Drozdyuk; 04.11.2016
comment
Вам нужно запустить процесс inets, используя inets:start(). Если вы хотите использовать SSL, вам также нужно сделать ssl:start(). Затем вы можете сделать httpc запросов. Обратите внимание, что это можно сделать автоматически, если вы добавите его в свой профиль .app. См. этот вопрос StackOverflow для получения дополнительной информации об этом. - person Andrakis; 07.11.2016
comment
Проблема заключалась в том, что оболочка rebar3 запускала inets автоматически. Смотрите принятый ответ. Спасибо за изучение этого в любом случае! - person Andriy Drozdyuk; 07.11.2016