Reputation: 1481
I have Erlang application which takes long time to start and even more to fully recompile. I make little changes which I'd like to test as fast as possible. I want to compile and load my changes without stopping the application. How to do it from Erlang console which I get to after starting the application? My source code is located in ./src
directory and beam files are compiled to ./ebin
directory and I want to do the same to the changed file.
My application is started with
erl -pa ebin deps/*/ebin
Upvotes: 3
Views: 1004
Reputation: 48599
You can do it by:
Loading the new version of the module, e.g. c(module_name)
Making a fully qualified call to a function in the new module. "Fully qualified" means:
module_name:function_name()
The module is only updated in the process where the fully qualified function call is made.
Here is an example:
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
In the shell:
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>
Upvotes: 5
Reputation: 56
Just to add to the other answers:
When you do a release, you may have two versions of your application and you may want to upgrade. Say, you first have lib/foo-1.0.0/ebin/foo_app.beam
loaded. Then you install foo-2.0.0
via your preferred method, I use target_system:install("foo", "/tmp/erl-target")
. Now I have /tmp/erl-target/lib/foo-2.0.0/
.
I use code:which(foo_app)
to see which one is loaded. To load it, in this case I would first start the Eshell as such:
$ /tmp/erl-target/bin/erl -boot /tmp/erl-target/releases/1/start
Afterwards I type:
1> application:ensure_all_started(foo).
{ok,[...,foo]}
To see which one is currently loaded, you type (in the same Eshell):
2> code:which(foo_app).
"/tmp/erl-target/lib/foo-1.0.0/ebin/foo_app.beam"
You will need the foo.appup
file in /tmp/erl-target/lib/foo-2.0.0/ebin/
with the following contents:
{"2.0.0",
[{"1.0.0",[{load_module,foo_app}]}],
[{"1.0.0",[{load_module,foo_app}]}]}.
To upgrade, you type:
3> release_handler:upgrade_app(foo, 'lib/foo-2.0.0').
{ok,[]}
If everything was successful, you will see the following:
4> code:which(foo_app).
"/tmp/erl-target/lib/foo-2.0.0/ebin/foo_app.beam"
If I added a new function in foo-2.0.0
which I exported, it will become available, for example.
If you want to downgrade back to the previous version, you will have to have a similar foo.appup
file in /tmp/erl-target/lib/foo-1.0.0/ebin/
, but with the version numbers swapped.
Please correct me if I am wrong, I am new to Erlang. I did test it myself and it worked for me. This is just to upgrade your application within a release, this is not upgrading the release itself.
If something is unclear, let me know. I am still trying to work this out myself. :)
Upvotes: 3
Reputation: 41528
Compile the module as you usually do, and then type this into the erlang shell:
l(my_module).
This will load code from the new my_module.beam
file and replace the my_module
module.
The old version might not go away completely - see the section on Code Reloading in the Erlang reference manual for details.
Upvotes: 2