OTP Design Principles: Gen_Event Behaviour
4575 ワード
1、事件処理の原則
OTPではevent managerはeventを受信できる名前付きオブジェクトです
イベントはerror、alarm、またはlogされるべき情報であってもよい
event managerにはevent handlerがインストールされます
event managerがeventを通知されると、eventはすべてのインストールされたevent handlerによって処理されます.
event managerはプロセスとして実装され、各event handlerはcallbackモジュールとして実装される
event managerは本質的に{Module,State}ペアのリストを維持し、各Moduleはevent handlerであり、Stateはevent handlerの内部状態である.
2、例
端末のcallbackモジュールにerrorメッセージを出力します.
ファイルのcallbackモジュールにerrorメッセージを書き込みます.
3 event managerを起動
event managerを起動してerrorを処理するには、次の方法を呼び出す必要があります.
このメソッドは新しいevent managerプロセスを起動し、接続します.
パラメータ{local,error_man}名前を指定します.ここでevent managerはローカルでerrorとして登録されています.man
gen_event:startは独立したevent managerを起動し、supervisorはありません.
4,event handlerの追加
event managerを起動し、event handlerを追加する例です.
gen_event:add_handlerはevent handerを追加するために使用されます
event managerはcallbackメソッドterminalを呼び出します.logger:init([])、パラメータ[]はadd_handlerの3番目のパラメータ
initは{ok,State}を返し,Stateはevent handlerの内部状態である.
5,通知event
error_manはevent managerの名前、no_replyはevent
イベントはイベントマネージャにメッセージとして送信されます
event受信後event managerはevent handlerごとにhandle_を呼び出すevent(Event,State)、呼び出し順序event handlerが追加した順序とは逆の順序
handle_イベントは{ok,State 1}を返し,State 1はevent handlerの新しい状態である.
6,event handlerの削除
イベントマネージャにメッセージを送信してterminalを削除します.loggerこのevent handler
コールバックメソッドterminal_も呼び出されます.logger:terminate([],State)、パラメータ[]はdelete_handlerメソッドの3番目のパラメータは、戻り値が無視されます.
7、停止
event mangerが停止すると、event handlerごとにterminate/2が呼び出されます.
7.1 supervision treeで
stopメソッドは不要
7.2独立したevent manager
stopメソッドを呼び出してevent managerを停止できます
補足:gen_event exports and callbacks
OTPではevent managerはeventを受信できる名前付きオブジェクトです
イベントはerror、alarm、またはlogされるべき情報であってもよい
event managerにはevent handlerがインストールされます
event managerがeventを通知されると、eventはすべてのインストールされたevent handlerによって処理されます.
event managerはプロセスとして実装され、各event handlerはcallbackモジュールとして実装される
event managerは本質的に{Module,State}ペアのリストを維持し、各Moduleはevent handlerであり、Stateはevent handlerの内部状態である.
2、例
端末のcallbackモジュールにerrorメッセージを出力します.
-module(terminal_logger).
-behaviour(gen_event).
-export([init/1, handle_event/2, terminate/2).
init(_Args) ->
{ok, []}.
handle_event(ErrorMsg, State) ->
io:format("***Error*** ~p~n", [ErrorMsg]),
{ok, State}.
terminate(_Args, _State) ->
ok.
ファイルのcallbackモジュールにerrorメッセージを書き込みます.
-module(file_logger).
-behaviour(gen_event).
-export([init/1, handle_event/2, terminate/2]).
init(File) ->
{ok, Fd} = file:open(File, read).
{ok, Fd}.
handle_event(ErrorMsg, Fd) ->
io:format(Fd, "***Error*** ~p~n", [ErrorMsg]),
{ok, Fd}.
terminate(_Args, Fd) ->
file:close(Fd).
3 event managerを起動
event managerを起動してerrorを処理するには、次の方法を呼び出す必要があります.
gen_event:start_link({local, error_man})
このメソッドは新しいevent managerプロセスを起動し、接続します.
パラメータ{local,error_man}名前を指定します.ここでevent managerはローカルでerrorとして登録されています.man
gen_event:startは独立したevent managerを起動し、supervisorはありません.
4,event handlerの追加
event managerを起動し、event handlerを追加する例です.
1> gen_event:start({local, error_man}).
{ok,<0.31.0>}
2> gen_event:add_handler(error_man, terminal_logger, []).
ok
gen_event:add_handlerはevent handerを追加するために使用されます
event managerはcallbackメソッドterminalを呼び出します.logger:init([])、パラメータ[]はadd_handlerの3番目のパラメータ
initは{ok,State}を返し,Stateはevent handlerの内部状態である.
init(_Args) ->
{ok, []}.
init(File) ->
{ok, Fd} = file:open(File, read),
{ok, Fd}.
5,通知event
3> gen_event:notify(error_man, no_reply).
***Error*** no_reply
ok
error_manはevent managerの名前、no_replyはevent
イベントはイベントマネージャにメッセージとして送信されます
event受信後event managerはevent handlerごとにhandle_を呼び出すevent(Event,State)、呼び出し順序event handlerが追加した順序とは逆の順序
handle_イベントは{ok,State 1}を返し,State 1はevent handlerの新しい状態である.
handle_event(ErrorMsg, State) ->
io:format("***Error*** ~p~n", [ErrorMsg]),
{ok, State}.
handle_event(ErrorMsg, Fd) ->
io:format(Fd, "***Error*** ~p~n", [ErrorMsg]),
{ok, Fd}.
6,event handlerの削除
gen_event:delete_handler(error_man, terminal_logger, []).
ok
イベントマネージャにメッセージを送信してterminalを削除します.loggerこのevent handler
コールバックメソッドterminal_も呼び出されます.logger:terminate([],State)、パラメータ[]はdelete_handlerメソッドの3番目のパラメータは、戻り値が無視されます.
terminate(_Args, _State) ->
ok.
terminate(_Args, Fd) ->
file:close(Fd).
7、停止
event mangerが停止すると、event handlerごとにterminate/2が呼び出されます.
7.1 supervision treeで
stopメソッドは不要
7.2独立したevent manager
stopメソッドを呼び出してevent managerを停止できます
> gen_event:stop(error_man).
ok
補足:gen_event exports and callbacks
gen_event module Callback module
gen_event:start_link
gen_event:start
gen_event:add_handler ----------------------> Module:init/1
gen_event:add_suphandler
gen_event:notify ---------------------------> Module:handle_event/2
gen_event:sync_notify
gen_event:call -----------------------------> Module:handle_call/2
gen_event:delete_handler -------------------> Module:terminate/2
gen_event:swap_handler ---------------------> Module1:terminate/2 Module2:init/1
gen_event:swap_sup_handler
gen_event:which_handlers
gen_event:stop -----------------------------> Module:terminate/2
Module:handle_info/2
Module:code_change/3