Hatena::ブログ(Diary)

cooldaemonの備忘録 RSSフィード

2007-07-17

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 を使うしかない。

添削・突っ込み 大歓迎。

はてなユーザーのみコメントできます。はてなへログインもしくは新規登録をおこなってください。

トラックバック - http://d.hatena.ne.jp/cooldaemon/20070717/1184676090