重新加载应用程序模块不会';t在基于erlang.mk的应用程序中生效
我正在使用Erlang.mk与Cowboy和Sync构建一个应用程序。除了重新加载应用程序模块不会';t在基于erlang.mk的应用程序中生效,erlang,cowboy,Erlang,Cowboy,我正在使用Erlang.mk与Cowboy和Sync构建一个应用程序。除了fragments\u app(fragments是我项目的名称)之外,重新编译对于大多数模块都非常有效。我在那里有一个路由配置,当我更改它(例如添加新路由)时,我会收到一个关于正在重新编译模块的通知: =INFO REPORT==== 14-Apr-2017::19:56:59 === /app/src/fragments_app.erl:0: Recompiled. =INFO REPORT==== 14-Apr-2
fragments\u app
(fragments是我项目的名称)之外,重新编译对于大多数模块都非常有效。我在那里有一个路由配置,当我更改它(例如添加新路由)时,我会收到一个关于正在重新编译模块的通知:
=INFO REPORT==== 14-Apr-2017::19:56:59 ===
/app/src/fragments_app.erl:0: Recompiled.
=INFO REPORT==== 14-Apr-2017::19:56:59 ===
fragments_app: Reloaded! (Beam changed.)
但这一变化似乎并不适用:
$ http :8080/fragments
HTTP/1.1 404 Not Found
content-length: 0
date: Fri, 14 Apr 2017 19:35:27 GMT
server: Cowboy
也在控制台中重新加载模块
c:l(fragments_app).
没用,也没用
sync:go().
如果我停止应用程序并再次启动它,它将按预期工作
同时,更新处理程序似乎立即生效-同步正在接收它,并且在不重新启动应用程序的情况下生效
以下是更改后fragments\u app.erl
的来源:
-module(fragments_app).
-behaviour(application).
-export([start/2]).
-export([stop/1]).
start(_Type, _Args) ->
Dispatch = cowboy_router:compile([
{ '_', [
{ "/fragments", fragments_http_handler, [] }
]}
]),
{ ok, _ } = cowboy:start_clear(fragments_http_listener, 100,
[{ port, 8080 }],
#{ env => #{ dispatch => Dispatch }}
),
fragments_sup:start_link().
stop(_State) ->
ok.
我的生成文件:
PROJECT = fragments
PROJECT_DESCRIPTION = New project
PROJECT_VERSION = 0.1.0
DEPS = cowboy sync
dep_cowboy_commit = master
DEP_PLUGINS = cowboy
SP = 2
include erlang.mk
和relx.config:
{release, {fragments_release, "1"}, [fragments, sasl, runtime_tools]}.
{extended_start_script, true}.
{sys_config, "rel/sys.config"}.
{vm_args, "rel/vm.args"}.
{dev_mode, true}.
为什么会这样?我能做些什么来应用我的更改而不重新启动应用程序?在Erlang VM中,可以加载任何模块代码的2个版本 然后,每个进程将继续执行其当前版本,直到使用完全限定的调用:module:function(Par…)调用其一个模块函数为止。在这种情况下,它将使用新的代码版本。这就是为什么使用OTP行为(提供代码更改回调)是有用的原因 这样做的原因是,每个流程“可以决定”何时应用更改,还可以调用函数来管理版本更改(例如,数据自适应) 模块
fragments\u app
具有应用程序行为,调用该模块仅用于启动和停止应用程序。如果希望应用任何更改,则需要调用它,并确保它已执行,因此需要调用序列
application:stop(fragments_app),
application:start(fragments_app),
...
请参见此处了解一些(正在进行的)讨论:谢谢@Pascal。这些绝对是有价值的见解。不幸的是,您提供的代码不适合我,我对Erlang没有足够的经验,无法将您的一般评论应用到我的具体问题中。我得到
{error,{not_start,fragments_app}}
。我认为这是特定于relx
的工作方式。您收到的消息意味着应用程序尚未启动。我不能说这是否正常。我不习惯relx,但是由于您的relx.config只引用片段,也许您应该测试“application:stop(fragments)”和“application:start(fragments)”