Erlang中的代码重新加载仅限于两个版本吗?

cns*_*nst 3 erlang upgrade real-time erlang-otp on-the-fly

Erlang能够轻松地重新加载代码,而不会丢弃现有的连接,这是一个非常有吸引力的主张,作为该语言的一个特性而广泛使用.

然而,没有明确宣传的是,显然,在删除尚未有机会将执行代码路径从旧切换为新的现有连接之前,您只能进行一次无缝重新加载.

确实如此,或者Erlang/OTP是否具有额外的高级代码重新加载功能,以避免在执行第二次代码重新加载时从上一代中删除执行代码路径?(我的意思是,nginx,例如,可以进行任意次数的二进制升级.)

Pas*_*cal 5

仅限2个版本.为了说明行为,我使用了小模块:

-module (tver).

-compile([export_all]).

start(Name) ->
    Pid = spawn(?MODULE,loop,[]),
    register(Name,Pid).

loop() ->
    receive
        % an internal call won't reload the code. The process keeps
        % executing the current version 
        version -> io:format("version 1~n"), loop();
        % an external call will reload the code. The process will use
        % the new version if any available in the VM. Notes that it
        % will not search in the path if a new version exists!
        update -> io:format("update code~n"), ?MODULE:loop();
        stop -> io:format("bye...~n")
    end.
Run Code Online (Sandbox Code Playgroud)

我在更改版本时更改打印的字符串.现在版本管理在行动:

Erlang/OTP 18 [erts-7.0] [64-bit] [smp:4:4] [async-threads:10]

Eshell V7.0  (abort with ^G)
1> c(tver).
{ok,tver}
2> tver:start(v1).
true
3> v1 ! version.
version 1
version
4> whereis(v1).
<0.39.0>
Run Code Online (Sandbox Code Playgroud)

将版本修改为版本2.c/1命令编译代码并将其加载到VM中

5> c(tver).        
{ok,tver}
Run Code Online (Sandbox Code Playgroud)

检查v1进程是否仍在执行版本1

6> v1 ! version.   
version 1
version
7> whereis(v1).    
<0.39.0>
Run Code Online (Sandbox Code Playgroud)

但是新生成的进程执行版本2.

8> tver:start(v2). 
true
9> v1 ! version.  
version 1
version
10> v2 ! version.
version 2
version
Run Code Online (Sandbox Code Playgroud)

外部调用强制使用新版本.在现实生活中,你应该做一些验证,比如旧版本,新版本是什么,升级是否可能,是否有一些数据需要适应......

11> v1 ! update. 
update code
update
12> v1 ! version.
version 2
version
13> v2 ! version.
version 2
version
14> whereis(v1).   
<0.39.0>
15> whereis(v2). 
<0.50.0>
Run Code Online (Sandbox Code Playgroud)

制作版本3,编译并重新加载

16> % modif version.
16> c(tver).        
{ok,tver}
17> whereis(v1).    
<0.39.0>
18> whereis(v2).    
<0.50.0>
19> v1 ! version.   
version 2
version
20> v1 ! version.   
version 2
version
21> v2 ! version.   
version 2
version
22> tver:start(v3). 
true
23> v2 ! version.  
version
version 2
24> v3 ! version.
version 3
version
Run Code Online (Sandbox Code Playgroud)

精细版本的pocesses 1和2正在执行版本2,而过程3正在执行版本3.

现在修改为版本4而不升级进程v1和v2,编译并加载代码.

25> c(tver).                                                  
{ok,tver}
26> whereis(v1).                                              
undefined
27> whereis(v2).                                              
undefined
Run Code Online (Sandbox Code Playgroud)

n-2版本不再存在!进程V1和V2已经死亡,尽管他们只是在等待接收块.在真正的OTP系统中,他们的主管会根据他们的重启策略重新启动它们.

28> tver:start(v4).                                           
true
29> whereis(v3).                            
<0.69.0>
30> whereis(v4).
<0.80.0>
Run Code Online (Sandbox Code Playgroud)

V3和V4进程分别执行版本3和4

31> v3 ! version.                                             
version
version 3
32> v4 ! version.
version 4
version
33>
Run Code Online (Sandbox Code Playgroud)