在erlang热代码替换 [英] Hot code replacement in erlang

查看:121
本文介绍了在erlang热代码替换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Erlang的第一个真正的项目上工作,但为了简洁起见,这段代码被简化了。我希望能够在远程运行的远程中加载较新版本的文件。我已经阅读了关于使用如$ code> gen_server 或 gen_fsm 这样的行为是免费的。虽然这可能会达到这个结果,我想用这个来学习如何做,而不仅仅是完成。我已阅读有关代码替换的文档,以及LYSE关于<一个href =http://learnyousomeerlang.com/designing-a-concurrent-application#hot-code-loving =noreferrer> Hot Code Loving ,除此之外,我还没有能够找到适合我正在做的事情,所以这里是基本的想法。

  -module(重新加载)。 

-export([loop / 0])。

loop() - >
收到
升级 - >
?MODULE:loop();
hello - >
io:format(这是一个测试〜n),
loop();
_ - >
loop()
结束。

我只是循环发送消息 upgrade ,它将加载较新版本的代码。

  $ erl 
Erlang R15B01 erts-5.9.1)[source] [64-bit] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.1(中止与^ G)
1> C(重装)。
{ok,reloading}
2> Loop = spawn(reloading,loop,[])。
< 0.39.0>
3>循环!你好。
这是一个测试
hello

此时我将10行更改为 io:format(我已经改变了!〜n),

  4>循环!升级。 
升级
5>循环!你好。
这是一个测试
hello

我期待这个 hello 调用打印我已经改变了这个!不是这是一个测试。我知道我可以简单地调用 c(重新加载)。并且这样工作的方式是预期的,但我正在寻找发送实际项目的消息,而不是手动更新代码。那么我的断开在哪里?我做错了什么,我应该做的是为了加载这个代码?如前所述,为了教育,我正在寻找一种非OTP解决方案。

解决方案

为了有一个明确的答案,我发布了这个。



使用 @rvirding 建议使用代码模块,我修改了它,如下所示:

   - 模(重装)。 

-export([loop / 0])。

loop() - >
收到
升级 - >
代码:purge(?MODULE),
编译:文件(?MODULE),
代码:load_file(?MODULE),
?MODULE:loop();
hello - >
io:format(这是一个测试〜n),
loop();
_ - >
loop()
结束。

首先代码:purge 旧的?MODULE ,然后 compile:file 新文件,最后, code:load_file 新的?MODULE
这个工作原来是我原来的意图。

  $ erl 
Erlang R15B01(erts-5.9.1) [source] [64-bit] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.1(中止与^ G)
1> Loop = spawn(reloading,loop,[])。
< 0.34.0>
2>循环!你好。
这是一个测试
hello

将行更改为 io:format(我已经改变了!〜n),

  3>循环!升级。 
升级
4>循环!你好。
我已经改变了这个!
hello


I am working on my first real project in erlang, however, this code is simplified for brevity. I want to be able to load a newer version of a file into my project remotely while it's running. I've read about using a behavior like gen_server or gen_fsm which has this for free. While that might achieve the result, I want to use this to learn how to do it, not just get it done. I've read the docs about code replacement, and LYSE's bit about Hot Code Loving, among other things, but I haven't been able to find anything that works for what I'm doing, so here is the basic idea.

-module(reloading).

-export([loop/0]).

loop() ->
    receive
        upgrade ->
            ?MODULE:loop();
        hello ->
            io:format("This is a test~n"),
            loop();
        _ ->
            loop()
    end.

I am simply looping with the idea that I can send the message upgrade and it will load a newer version of the code.

$ erl
Erlang R15B01 (erts-5.9.1) [source] [64-bit] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.1  (abort with ^G)
1> c(reloading).
{ok,reloading}
2> Loop = spawn(reloading, loop, []).
<0.39.0>
3> Loop ! hello.
This is a test
hello

At this point I change 10 line to io:format("I have changed this!~n"),

4> Loop ! upgrade.
upgrade
5> Loop ! hello.  
This is a test
hello

I am expecting this hello call to print I have changed this! not This is a test. I know I can simply call c(reloading). and have this work the way expected, but I'm looking to send the actual project a message rather than manually updating the code. So where is my disconnect? What am I doing wrong, that I should be doing in order to hot load this code? As mentioned before, I am looking for a non-OTP solution for the sake of education.

解决方案

For the sake of having an explicit answer, I am posting this.

Using @rvirding's suggestion of using the code module, I've modified it to look like this:

-module(reloading).

-export([loop/0]).

loop() ->
    receive
        upgrade ->
            code:purge(?MODULE),
            compile:file(?MODULE),
            code:load_file(?MODULE),
            ?MODULE:loop();
        hello ->
            io:format("This is a test~n"),
            loop();
        _ ->
            loop()
    end.

First code:purge the old ?MODULE, then compile:file the new file, and finally, code:load_file the new ?MODULE. This works as I originally intended.

$ erl
Erlang R15B01 (erts-5.9.1) [source] [64-bit] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.1  (abort with ^G)
1> Loop = spawn(reloading, loop, []).
<0.34.0>
2> Loop ! hello.
This is a test
hello

Change line to io:format("I have changed this!~n"),

3> Loop ! upgrade.                   
upgrade
4> Loop ! hello.  
I have changed this!
hello

这篇关于在erlang热代码替换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆