使用rebar3时,如何为httpc的配置文件设置配置选项?
这是唯一的例子通过是erl -config inets.config看起来像这样:
[{inets,
[{services,[{httpc,[{profile, server1}]},
{httpc, [{profile, server2}]}]}]
}].
Run Code Online (Sandbox Code Playgroud)
我尝试将其应用于rebar3项目结构。
该项目是使用rebar3创建的,具有标准的OTP布局:
rebar3 new release myapp
Run Code Online (Sandbox Code Playgroud)
这是我的myapp/config/sys.config:
[
{ myapp, []},
{inets, [{services, [{httpc, [{profile, myapp}]}]}]}
].
Run Code Online (Sandbox Code Playgroud)
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}]}]
}]
}.
Run Code Online (Sandbox Code Playgroud)
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, []}
]}.
Run Code Online (Sandbox Code Playgroud)
这是我要从rebar`s shell发出的请求:
$ ./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)
Run Code Online (Sandbox Code Playgroud)
这是没有配置文件的请求,用于检查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"},...
Run Code Online (Sandbox Code Playgroud)
rebar3本身使用inets http客户端,因此当它在shell中启动您的应用程序时,inets已经启动并配置。一种解决方法是在应用程序启动之前停止inet,这是rebar3开发人员建议的(在下面复制)。另一个是在控制台模式下引导您的发行版:
./_build/default/rel/myapp/bin/myapp console
Run Code Online (Sandbox Code Playgroud)
除此之外,您的项目还有另一个问题。您尚未告诉您要为您启动inets。您应该在myapp.src:
{applications, [kernel, stdlib, inets]}
Run Code Online (Sandbox Code Playgroud)
或者,您可以在rebar.config发布部分列出inets ,以告诉relx该应用程序应包含在发布中并在启动时启动。
{relx, [{release, { myapp, "0.1.0" }, [inets, myapp, sasl]} ]}
Run Code Online (Sandbox Code Playgroud)
以下是rebar3邮件列表中Fred Hebert 的完整答案的副本:
我们确实需要inets来进行程序包获取,并且可能不会在所有使用情况下都将其自动关闭,因为如果用户应用程序不使用inets但仍要求在后续运行中获取程序包,这可能会损害rebar3代理的常规用法。 。我建议的解决方法是对其使用钩子脚本。挂钩脚本在引导用户应用程序之前运行,并且是常规脚本:
Run Code Online (Sandbox Code Playgroud)#!/usr/bin/env escript main(_) -> application:stop(inets).然后,您可以使用以下命令将脚本挂钩:
Run Code Online (Sandbox Code Playgroud){shell, [{script_file, "path/to/file"}]}在rebar3.config中,或
Run Code Online (Sandbox Code Playgroud)rebar3 shell --script_file test/check_env.escript