Hot Code Upgrade
Reload a module's code without stopping the running system.
Code
% Step 1: write a new version of counter.erl with extra functionality
% Step 2: compile and load it
c(counter). % compiles and loads counter.erl
% or: code:load_file(counter).
% Step 3: existing processes continue running the OLD code until
% they execute a fully-qualified call (Module:Function), which
% forces them to switch to the latest version.
% In a gen_server, use code_change/3 to migrate state:
-code_change({down, "1.0.0"}).
code_change(_OldVsn, State, _Extra) ->
%% Transform old State to new State
{ok, State}.
% Release handling with relups:
% 1. Build a release with the new code
% 2. Generate a relup (sequence of app_stop/code_change/app_start)
% 3. Run appup:install_release/1 to apply it hot
%
% Tools: relx (builds releases), systools (relups), and
% OTP's appup files describe the upgrade per-application.
% Two versions of a module can coexist: the 'current' and 'old'
% version. A third load purges the old one; processes still on it
% are killed with reason 'kill'.Explanation
BEAM can hold two versions of a module simultaneously: the current (newest) and the old. A running process keeps executing the old code until it makes a fully-qualified call (Module:Function), at which point it jumps to the new code. gen_server's code_change/3 callback gives you a hook to transform the process state when this happens. This is the basis of Erlang's legendary non-stop systems — you can upgrade a telecom switch without dropping a single call.
More Erlang Snippets
Ping-Pong Processes
Two processes pass messages back and forth using spawn and receive.
gen_server Counter
Build a stateful server with the gen_server behaviour.
Supervisor Tree
Define a supervisor that starts workers and restarts them on crash.
Selective Receive with References
Match a specific reply out of many messages using a unique reference.
Links, Exit Trapping & 'Let It Crash'
Use link and trap_exit to detect process death and recover.
Stateful Server via Tail Recursion
Hold mutable state in a process by threading it through recursive calls.