Dynamic Code Loading
某所で apache に負荷をかける為に erlang を使おうとして、知らずに http module を上書きしててハマったという書き込みをみて、Programming Erlang の APPENDIX E. Dynamic Code Loading の内容を思い出したので紹介。
まず、下記の source code を準備。
-module(a). -compile(export_all). start(Tag) -> spawn(?MODULE, loop, [Tag]). loop(Tag) -> V = b:x(), io:format("Ver1 ~p : ~p~n", [Tag, V]), timer:sleep(3000), loop(Tag).
-module(b). -compile(export_all). x() -> 1.
コンパイルして実行開始。
% erl 1> c(a). {ok,a} 2> c(b). {ok,b} 3> a:start(one). Ver1 one : 1 Ver1 one : 1 4> a:start(two). Ver1 two : 1 Ver1 one : 1 Ver1 two : 1 Ver1 one : 1
module b のコードを書き換える。(この時、上記で実行した erl を停止しない)
-module(b). -compile(export_all). x() -> 2.
起動しっぱなしの erl で module b をコンパイルする。
Ver1 one : 1 Ver1 two : 1 5> c(b). {ok,b} Ver1 one : 2 Ver1 two : 2
b:x/0 の戻り値が変わった事が即反映される。
更に、module a を書き換える。
-module(a). -compile(export_all). start(Tag) -> spawn(?MODULE, loop, [Tag]). loop(Tag) -> V = b:x(), io:format("Ver2 ~p : ~p~n", [Tag, V]), timer:sleep(3000), loop(Tag).
起動しっぱなしの erl で module a をコンパイルして、a:start/1 を実行する。
Ver1 one : 2 Ver1 two : 2 6> c(a). {ok,a} Ver1 one : 2 Ver1 two : 2 6> start:a(three). Ver2 three : 2 Ver1 one : 2 Ver1 two : 2 Ver2 three : 2
spawn された Ver1 は動作し続けている事が解る。
erlang では、無停止運用の為に、動的にコードが読み込まれる特性を理解してコードを書く事が大切。