主页

索引

模块索引

搜索页面

gen_event模块

回调函数:

gen_event module                   Callback module
----------------                   ---------------
gen_event:start
gen_event:start_link       ----->  -

gen_event:add_handler
gen_event:add_sup_handler  ----->  Module:init/1

gen_event:notify
gen_event:sync_notify      ----->  Module:handle_event/2

gen_event:call             ----->  Module:handle_call/2

-                          ----->  Module:handle_info/2

gen_event:delete_handler   ----->  Module:terminate/2

gen_event:swap_handler
gen_event:swap_sup_handler ----->  Module1:terminate/2
                                   Module2:init/1

gen_event:which_handlers   ----->  -

gen_event:stop             ----->  Module:terminate/2

-                          ----->  Module:code_change/3

add_handler/3

结构:

add_handler(EventMgrRef, Handler, Args) -> Result
类型:
EventMgrRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
Handler = Module | {Module,Id}
Args = term()
Result = ok | {'EXIT',Reason} | term()
   Reason = term()

Handler:

Module: 回调模块
{Module,Id}: 当多个event handler用同一个回调模块时,用于指定event handler的唯一标识
Args: Module:init/1函数的传参

add_sup_handler/3

结构:

add_sup_handler(EventMgrRef, Handler, Args) -> Result
类型
EventMgrRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
Handler = Module | {Module,Id}
Args = term()
Result = ok | {'EXIT',Reason} | term()

说明:

类似add_handler/3
不同:
  1.当调用进程以Reason原因终止时,
  event manager会用参数为{stop,Reason}的方法Module:terminate/2删除此event handler
  2.当event handler之后被删除时,
  event manager会发送消息{gen_event_EXIT,Handler,Reason}给调用进程
  其中,Reason有:
    normal
    shutdown
    {swapped,NewHandler,Pid}
    error()

call/3/4

结构:

call(EventMgrRef, Handler, Request) -> Result
call(EventMgrRef, Handler, Request, Timeout) -> Result
类型:
EventMgrRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
   Name = Node = atom()
   GlobalName = ViaName = term()
Handler = Module | {Module,Id}
   Module = atom()
   Id = term()
Request = term()
Timeout = int()>0 | infinity
Result = Reply | {error,Error}
   Reply = term()
   Error = bad_module | {'EXIT',Reason} | term()
      Reason = term()

说明:

发送一个同步请求,等待返回值或超时发生
EventMgrRef, Handler: 参见add_handler/3
Request: 转发给handle_call函数
Timeout: 默认为5000
Result:
   {error, bad_module}: % If the specified event handler is not installed,
   {error, {'EXIT', Reason}}: % If the callback function fails with Reason
   {error, Term}: % If the callback function returns an unexpected value Term

delete_handler/3

结构:

delete_handler(EventMgrRef, Handler, Args) -> Result
类型:
EventMgrRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
   Name = Node = atom()
   GlobalName = ViaName = term()
Handler = Module | {Module,Id}
   Module = atom()
   Id = term()
Args = term()
Result = term() | {error,module_not_found} | {'EXIT',Reason}

说明:

从事件管理EventMgrRef中删除event handler
Args: 此参数会传给Module:terminate/2的第1个参数
返回值: 是函数Module:terminate/2的返回值

Result:

{error,module_not_found}: 如果没有安装此handler
{'EXIT',Reason}: 如果回调函数失败

notify/2

参见sync_notify/2

sync_notify/2

结构:

notify(EventMgrRef, Event) -> ok
sync_notify(EventMgrRef, Event) -> ok
类型:
EventMgrRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
Event = term()

说明:

event manager EventMgrRef会调用每个安装了此event的event handler
  的回调函数Module:handle_event/2
notify是异步请求,立即返回
sync_notify/2是同步请求,在所有的event handlers都处理完后返回ok

其他:

notify/1 does not fail even if the specified event manager does not exist,
   unless it is specified as Name.

which_handlers/1

结构:

which_handlers(EventMgrRef) -> [Handler]
类型:
EventMgrRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
   Name = Node = atom()
   GlobalName = ViaName = term()
Handler = Module | {Module,Id}
   Module = atom()
   Id = term()

实例

terminal_logger.erl:

-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.

file_logger.erl:

-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).

启动:

// start_link通常用于supervisor监控树
// start通常用于单独的事件管理
1> gen_event:start({local, error_man}).
{ok,<0.31.0>}
// 此函数会调用terminal_logger:init([])
2> gen_event:add_handler(error_man, terminal_logger, []).
ok
// 对file_logger类事件来说, 会调用
// terminal_logger:init([])

增加handler:

3> gen_event:add_handler(error_man, file_logger, ["/tmp/file.txt"]).
// 会调用
// file_logger:init(["/tmp/file.txt"])

消息发送:

4> gen_event:notify(error_man, no_reply).
// 会调用回调函数
1.对terminal_logger:
handle_event(ErrorMsg, State) ->
  io:format("***Error*** ~p~n", [ErrorMsg]),
  {ok, State}.
2.对file_logger:
handle_event(ErrorMsg, Fd) ->
  io:format(Fd, "***Error*** ~p~n", [ErrorMsg]),
  {ok, Fd}.

删除handler:

5> gen_event:delete_handler(error_man, terminal_logger, []).
ok
6> gen_event:delete_handler(error_man, file_logger, []).
ok

停止:

> gen_event:stop(error_man).
ok

处理其他消息:

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

code_change(OldVsn, State, Extra) ->
  ..code to convert state (and more) during code change
  {ok, NewState}

主页

索引

模块索引

搜索页面