Erlang Hot Code Loading

| Comments

Nearly every posting about Erlang that you come across mentions the hot code loading feature, aka dynamic code loading. But so far I have had problems finding a simple example of how to add this to my code. So here is one.

Copy this code into an editor. I’m using Emacs here, so all instructions use it’s keybindings.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
%% A process whose only job is to keep a counter.
-module(counter).
-export([start/0, codeswitch/1]).

start() -> loop(0).

loop(Sum) ->
  receive
    {increment, Count} ->
      loop(Sum+Count);
    {print} ->
      io:format("Sum is ~p~n", [Sum]),
      loop(Sum);
    {counter, Pid} ->
      Pid ! {counter, Sum},
      loop(Sum);
    code_switch ->
      ?MODULE:codeswitch(Sum);
    M ->
      io:format("Unhandled message ~p~n", [M]),
      loop(Sum)
   end.

codeswitch(Sum) -> loop(Sum).

Compile and start a new erlang shell, Ctrl-C Ctrl-K.

Now we want to start a new process running this code. Startup and enter the following code into the erlang shell.

1
2
3
4
5
Erlang R15B (erts-5.9) [source] [64-bit] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9  (abort with ^G)
1> Pid = spawn(fun() -> counter:start() end).
<0.37.0>

Send the process a message to make sure it’s alive and working.

1
2
3
4
5
3> Pid ! {increment, 3}.
{increment,3}
4> Pid ! {print}.
Sum is 3
{print}

Now that we have the first version of the process running, add a new clause to the receive like so.

1
2
3
4
5
6
7
8
  {print} ->
    io:format("Sum is ~p~n", [Sum]),
    loop(Sum);
  {reset} ->
    loop(0);
  {counter, Pid} ->
    Pid ! {counter, Sum},
    loop(Sum);

Compile this version, Ctrl-C Ctrl-K and send a message to the process that only the new version can handle.

1
2
3
6> Pid ! {reset}.
Unhandled message {reset}
{reset}

So we are still running the previous version of the code.

1
2
3
4
5
6
7
8
9
10
6> Pid ! code_switch.
code_switch
7> Pid ! {print}.
Sum is 3
{print}
8> Pid ! {reset}.
{reset}
9>  Pid ! {print}.
Sum is 0
{print}

The ‘code_switch’ message makes the process load the new version of code. So using this you can upgrade the running process without losing state. Cool.

Comments