我可以在不停止运行应用程序的情况下重新加载单个更改的 Erlang 模块吗?

And*_*yKo 3 erlang

我有 Erlang 应用程序,它需要很长时间才能启动,甚至需要更长时间才能完全重新编译。我做了一些我想尽快测试的小改动。我想在不停止应用程序的情况下编译和加载我的更改。如何从启动应用程序后进入的 Erlang 控制台执行此操作?我的源代码位于./src目录中,梁文件被编译到./ebin目录中,我想对更改后的文件执行相同的操作。我的应用程序开始于

erl -pa ebin deps/*/ebin
Run Code Online (Sandbox Code Playgroud)

7st*_*tud 5

你可以这样做:

  1. 加载模块的新版本,例如 c(module_name)

  2. 对新模块中的函数进行完全限定调用。“完全合格”是指:

     module_name:function_name()
    
    Run Code Online (Sandbox Code Playgroud)

    该模块仅在进行完全限定函数调用的过程中更新。

下面是一个例子:

a.erl:

-module(a).
-compile(export_all).

start() -> 
    %% Long startup time:
    timer:sleep(1000), 

    spawn(fun() -> loop() end).

loop() ->
    receive
        {a, Msg} -> 
            show1(Msg),
            loop();
        {b, Msg} -> 
            show2(Msg),
            loop();
        update_code -> a:loop()
    end.

show1(Arg) ->
    %%io:format("Hello ~w!~n", [Arg]).  %original code
    io:format("XXX ~w!~n", [Arg]).  %new code

show2(Arg) ->
    %%io:format("Goodbye ~w!~n", [Arg]).  %original code      
    io:format("YYY ~w!~n", [Arg]).  %new code
Run Code Online (Sandbox Code Playgroud)

在外壳中:

1> c(a).           
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

2> Pid = a:start().
<0.72.0>

3> a:show1(jane).  %%Executed by shell process.
Hello jane!
ok

4> Pid ! {a, jane}. %% show1/1 executed in spawned process.
Hello jane!
{a,jane}

5> c(a).           
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

6> a:show1(jane).  %%Module updated in shell process.
XXX jane!
ok

7> Pid ! {a, jane}.
Hello jane!     <---- STILL EXECUTING OLD MODULE
{a,jane}

8> Pid ! update_code.  %% Make fully qualified function call in spawned process.
update_code

9> Pid ! {a, jane}.  %% The whole module has been replaced by new code.
XXX jane!
{a,jane}

10> Pid ! {b, jane}.   
YYY jane!
{b,jane}

11> 
Run Code Online (Sandbox Code Playgroud)