Tokyo.ex #8 (2017/11/26)
"current"と"old"
currentとoldのコードはどちらも実行可能currentを使う
currentにcurrentをoldにするoldを捨てる
oldを実行中のプロセスはbrutal kill
oldからcurrentに切り替わるようにしなければならない
GenServerなどを書いてればだいたい大丈夫oldを消してcurrentだけにしようとする
old実行中プロセスがkillされる:release_handler.make_permanent/1をテキトーに呼ぶと危険loop.exなどとして保存> c("loop.ex")> spawn_link(fn -> Loop.loop(0) end)> c("loop.ex")を試すdefmodule Loop do
def loop(n) do
Enum.each(1..20, fn i ->
:timer.sleep(1_000)
IO.inspect({n, i, str(), __MODULE__.str()}) # local and remote call
end)
__MODULE__.loop(n + 1) # remote and tail-recursive call
end
def str() do
"str/0 version1" # change this and reload!
end
end
loop/1の末尾再帰のとき
GenServerなど)code_change/3 callbackでデータ移行code_change/3のデメリットcode_change/3でデータ移行”もここで指定appupファイル群をまとめたもの:release_handler.install_release/2で取り込む(hot code upgrade):release_handler.upgrade_app/2で取り込む(hot code upgrade)code_change/3しない
updateではなくload_moduleを使う単純なappupを生成するツールを自作code_change/3を使わない理由:init.restart/0になるcode_change/3のためにテスト書きたくない
code_change/3の代替案code_change/3に相当するコードをhandle_*の最初に呼び出してデータ移行することもあるGenServerばかり書いているとcode_change/3が目立つが、これが役に立つのは限られた状況のみ