[erlang-questions] Dynamic code reloading

Jeffm <>
Wed Apr 21 04:04:50 CEST 2010


Was sitting around waiting for a meeting this morning and thought I'd 
create this to clarify erlang hot code updates.:

Summary: The following uses this example module to demonstrate hot code 
loading without the use of OTP and one possible reason why a process may 
die during a hot code update.

%%%%% Start of file hot.erl %%%%%
%%
%% Simple example of hot code update.
%%
-module(hot).

-export([
          start/0,
          loop/0
         ]).


-define(V, 4).

start() ->
     spawn(?MODULE, loop, []).

loop() ->
     receive
         print_version ->
             io:format("~p current version is ~p~n", [?MODULE, ?V]),
             hot:loop();
         Other ->
             io:format("~p got message ~p~n", [?MODULE, Other]),
             hot:loop()
     end.

%%%%% End hot.erl %%%%%

start erl at a unix shell and...

compile and load code:

1> c(hot).
{ok,hot}

Start the process:

2> P = hot:start().
<0.42.0>

check presence
3> i().
...
<0.42.0>              hot:loop/0                             233        
1    0
                       hot:loop/0                               1
Total                                                      24633   
706328    0
                                                              224
ok

Say hello:

4> P ! "hello".
hot got message "hello"
"hello"

check version:

5> P ! print_version.
hot current version is 1
print_version

Edit hot.erl in a text editor in another window and change
-define(V, 1).
to
-define(V,2).

Compile and load new code:

6> c(hot).
{ok,hot}

Check version:

7> P ! print_version.
hot current version is 1
print_version

Notice it hasn't changed. Check again:

8> P ! print_version.
hot current version is 2
print_version

It's now version two as it's re-entered the loop. Now to break it:

Edit hot.erl again setting V to 3, then compile and load with

9> c(hot).
{ok,hot}

check still running with

10> i().
....
<0.42.0>              hot:loop/0                             233       
61    0
                       hot:loop/0                               1
Total                                                      26607   
749896    0
                                                              224
ok

Edit hot.erl setting V to 4, then compile and load,

11> c(hot).
{ok,hot}

Check for presence of process,
12> i().
<0.35.0>              erlang:apply/2                        2584    
47585    0
                       c:pinfo/1                               49
Total                                                      27361   
780079    0
                                                              223
ok

The process has died! This is due to version 2 of the code being 
unloaded to make room for version 4, version 3 and 4 now being in 
memory, before the process had looped and exited version 2 and started 
using version 3 as it is blocked on the receive waiting for a message. 
One possible fix for this is to have an 'update' message which does 
nothing except cause the process to loop in order to load new code when 
loaded by sending each process affected the update message after the new 
code is loaded.

Hope that clarifies things,

Jeff.



More information about the erlang-questions mailing list