Recently I tried “recompile” function/macro in iex out of curiosity (usually I just ctrl+c twice and run previous command) and I just can’t wrap my head around it.
Consider following example GenServer:
defmodule App.Worker do
use GenServer
def start_link(_) do
GenServer.start_link(__MODULE__, nil)
end
@impl true
def init(_) do
send(self(), :increment)
{:ok, 1}
end
@impl true
def handle_info(:increment, state) do
Process.send_after(self(), :increment, 1000)
state = state + 1
IO.inspect("Counter: #{state}, process: #{self() |> inspect}")
{:noreply, state}
end
end
If I start it with iex -S mix it prints a sequence of 1,2,3 etc. All good. Now I edit the code to add 10 instead of 1 on each increment, recompile() in iex, and I see that new code runs, but with OLD state. E.g. if I recompile when the counter was at 11, next output will be 21.
It seems that the process and the state that it was is not restarted with recompile (same pid, same state), but new updated functions work with the same process and state.
I can’t seem to find anything in documentation that would describe this behaviour.
I thought that it was the famous “hot code reload”, I tried implementing code_change callback in this GenServer, but it seems it is never called on recompile, so it must be something else.






















