supervisor
仕事が落ち着いたので、erlang 勉強再開。
id:cooldaemon:20070625 と id:cooldaemon:20070630 で作った server を supervisor tree に入れてみた。
-module(sup). -behaviour(supervisor). -export([start_link/1, stop/0]). -export([init/1, worker_spec/2]). start_link(Code) -> supervisor:start_link({local, ?MODULE}, ?MODULE, [Code]). stop() -> case whereis(?MODULE) of Pid when pid(Pid) -> exit(Pid, shutdown), ok; _ -> not_started end. init(Code) -> Flags = {one_for_one, 0, 1}, Children = [ worker_spec(counter, []), worker_spec(code_lock, [Code]) ], {ok, {Flags, Children}}. worker_spec(WokerModule, Args) -> StartFunc = {WokerModule, start_link, Args}, {WokerModule, StartFunc, permanent, brutal_kill, worker, [WokerModule]}.
sup:start_link("abcd"). で counter と code_lock が起動し、sup:stop(). で全てが停止する。
proc_lib で echoserver を書き直した
gen_server、supervisor、proc_lib の三つを押さえれば、httpd.erl の起動と停止の動作を理解する事が可能。
って事で、以前 みかログ: Erlang で echo server こちらで添削して頂いた id:cooldaemon:20070614 を proc_lib で書き直してみた。
-module(echoserver3). -export([start_link/0, stop/0]). -export([init/1, accept/1, handle_connection/1, recv_loop/1]). start_link() -> proc_lib:start_link(?MODULE, init, [self()]). stop() -> case whereis(?MODULE) of Pid when pid(Pid) -> exit(Pid, shutdown), ok; _ -> not_started end. init(Parent) -> register(?MODULE, self()), case gen_tcp:listen( 8080, [{active, false}, binary, {packet, line}, {reuseaddr, true}] ) of {ok, ListenSocket} -> proc_lib:init_ack(Parent, {ok, self()}), accept(ListenSocket); {error, Reason} -> proc_lib:init_ack(Parent, {error, Reason}), error end. accept(ListenSocket) -> {ok, Socket} = gen_tcp:accept(ListenSocket), spawn_link(?MODULE, handle_connection, [Socket]), accept(ListenSocket). handle_connection(Socket) -> gen_tcp:send(Socket, <<"hello\r\n">>), recv_loop(Socket). recv_loop(Socket) -> case gen_tcp:recv(Socket, 0) of {ok, B} -> case B of <<"bye\r\n">> -> gen_tcp:send(Socket, <<"cya\r\n">>), gen_tcp:close(Socket); Other -> gen_tcp:send(Socket, Other), recv_loop(Socket) end; {error, closed} -> ok end.
gen_server 等の behaviour は、proc_lib を元に作られている。よって、特にステータス管理を行わないのであれば、proc_lib で十分。
処理をブロックするなら gen_server を選択できないので proc_lib を使うしかない。
添削・突っ込み 大歓迎。