OTP Design Principles: Gen_Server Behaviour


OTP Design Principles: Gen_Server Behaviour
1,Client-Serverの原則
Client-serverモデルは、1つのセンターサーバと任意の複数のクライアントから構成されています.
このモデルは主にリソース管理操作に用いられ、異なるクライアントは共通のリソースを共有し、サーバはリソースの管理を担当する.
2、例

-module(ch3).
-behaviour(gen_server).

-export([start_link/0]).
-export([alloc/0, free/1]).
-export([init/1, handle_call/3, handle_cast/2]).

start_link() ->
  gen_server:start_link({local, ch3}, ch3, [], []).

alloc() ->
  gen_server:call(ch3, alloc).

free(Ch) ->
  gen_server:cast(ch3, {free, Ch}).

init(_Args) ->
  {ok, channels()}.

handle_call(alloc, _From, Chs) ->
  {Ch, Chs2} = alloc(Chs),
  {reply, Ch, Chs2}.

handle_cast({free, Ch}, Chs) ->
  Chs2 = free(Ch, Chs),
  {noreply, Chs2}.

3,Gen_を起動するServer
ch3:start_link():

start_link() ->
  gen_server:start_link({local, ch3}, ch3, [], []) => {ok, Pid}

gen_server:start_link/4は新しいプロセスを開始し、接続します.新しいプロセスはgenです.server
1)最初のパラメータ指定gen_サーバ名,{local,ch 3}はgen_をローカルに登録することを示す.サーバプロセスはch 3
2)2番目のパラメータはcallback moduleをch 3として指定し、ここでインタフェースメソッドとcallbackメソッドはいずれもmoduleに配置され、これは良いプログラミング実践である.
3)3番目のパラメータはinitメソッドのパラメータを指定する
4)4番目のパラメータはoptions
名前の登録に成功した場合、新しいgen_serverプロセスはcallbackメソッドch 3:init([])を呼び出し{ok,State}を返す
gen_server:start_linkはgen_まで同期しますサーバは初期化され、要求を受信してから戻ることができます.gen_server:start_linkはsupervisorによって起動され、supervision treeの一部です.
gen_server:startは個別のプロセスを開始し、gen_server:startはsupervision treeの一部ではありません.supervisorはありません.
4、同期要求――Call
同期要求alloc()はgen_server:call/2実装:

alloc() ->
  gen_server:call(ch3, alloc).

ch 3はgen_serverの名前、allocは実際のリクエストです
このリクエストはgenにメッセージを送信します.サーバ、リクエストが受け入れられたらgen_server呼び出しhandle_コール(Request,From,State)を返し{replay,Replay,State 1}を返します.
5、非同期要求——Cast
非同期要求free(Ch)由gen_server:cast/2実装

free(Ch) ->
  gen_server:cast(ch3, {free, Ch}).

ch 3はgen_serverの名前、{free,Ch}は本当のリクエストです
callbackメソッドはhandle_cast(Request,State),は{noreply,State 1}を返す.
6、クローズ
6.1 Supervision Treeで
gen_serverはsupervision treeの一部でありstopメソッドは必要ありません.gen_serverはsupervisorによって自動的にオフになります.
gen_を閉じる必要がある場合はサーバの前にクリーンアップを行うにはshutdown strategyがtimeoutでgen_serverのinitメソッドでexit信号をキャプチャする設定
gen_サーバは、クローズ時にcallbackメソッドterminate(shutdown,State)を呼び出します.

init(Args) ->
  ...,
  process_flag(trap_exit, true),
  ...,
  {ok, State}.
...
terminate(shutdown, State) ->
  ..code for cleaning up here..
  ok.

6.2個別Gen_Servers
gen_serverはsupervision treeの一部ではありません.stopメソッドを定義すると便利です.

...
export([stop/0]).
...
stop() ->
  gen_server:cast(ch3, stop).
...

handle_cast(stop, State) ->
  {stop, normal, State};
handle_cast({free, Ch}, State) ->
  ...
...

terminate(normal, State) ->
  ok.

callbackメソッドはstopリクエストを処理し、{stop,normal,State 1}を返します.normaは正常なクローズであることを指定します.State 1はgen_です.serverのstateの新しい値
これによりgen_serverはterminate(normal,State 1)を呼び出し、優雅にサーバを閉じる
7、その他のメッセージの処理
gen_serverはリクエスト以外のメッセージを受け入れることができ、callbackメソッドhandle_info(Info,State)はそれらを処理するために実装されなければならない.
例えばgen_serverはsupervisorが考えている他のプロセスに接続され、exit信号を取得すると、exitメッセージが受信されます.

handle_info({'EXIT', Pid, Reason}, State) ->
  ..code to handle exits here..
  {noreply, State1}.

補足:gen_server exports and callbacks

gen_server module              callback module
gen_server:start_link -------> Module:init/1
gen_server:start
gen_server:call -------------> Module:handle_call/3
gen_server:multi_call
gen_server:cast -------------> Module:handle_cast/2
gen_server:abcast              
gen_server:replay
gen_server:enter_loop
                               Module:handle_info/2
                               Module:terminate/2
                               Module:code_change/3