Erlang OTP gen_event (1)

3 篇文章 0 订阅
2 篇文章 0 订阅
演示gen_event的运行过程:

mod_event_manager.erl:事件管理器:
mod_event_error_msg.erl: 错误日志事件:把错误放入对应的txt用。


[img]http://dl2.iteye.com/upload/attachment/0094/2453/f906bdee-cd85-3171-83ab-46ec581a289c.png[/img]


[img]http://dl2.iteye.com/upload/attachment/0094/2455/9d88e34a-975c-3c05-b682-8ffa3fc9dae6.png[/img]


[img]http://dl2.iteye.com/upload/attachment/0094/2457/7850d7af-84c6-3508-b39e-95b6774f99d9.png[/img]


[img]http://dl2.iteye.com/upload/attachment/0094/2459/24f32852-3416-30c2-8ea5-7835ed673c06.png[/img]


[img]http://dl2.iteye.com/upload/attachment/0094/2461/0efce12e-d288-3738-bf13-f90d1e498c0d.png[/img]


[img]http://dl2.iteye.com/upload/attachment/0094/2463/49a9142d-55b5-3364-b788-a72b17baa5c7.png[/img]


%%%-------------------------------------------------------------------
%%% @author zhongwencool@gmail.com
%%% @copyright (C) 2014, <COMPANY>
%%% @doc event manager center
%%%
%%% @end
%%%-------------------------------------------------------------------
-module(mod_event_manager).
-author("zhongwencool@gmail.com").

%% API
-export([start/0,start_link/0,stop/0,add_handler/2,add_sup_handler/2,del_handler/2]).

-export([notify_error_msg/1,sync_notify_error_msg/0,call_open_file/0,call_close_file/0,which_handlers/0]).

-define(SERVER, ?MODULE).

%% @doc Creates a stand-alone event manager process,
%% i.e. an event manager which is not part of a supervision tree and thus has no supervisor.
start() ->
gen_event:start({local,?SERVER}).

%% @doc Creates an event manager process as part of a supervision tree
%% @spec start_link() -> {ok, Pid} | {error, {alread_started,Pid}}
start_link() ->
gen_event:start_link({local,?SERVER}).

stop() ->
gen_event:stop(?SERVER).

%% @doc Adds a new event handler to the event manager
%%The event manager will call Module(Handler):init/1 to terminate the event handler.
-spec add_handler(Handler,Args) -> ok | {'EXIT',Reason} | term() when
Handler::Module | {Module,Id},
Args::term(),
Module::atom(),
Id::term(),
Reason::term().

add_handler(Handler,Args) ->
gen_event:add_handler(?SERVER,Handler,Args).

%% @doc Adds a new event handler in the same way as add_handler/3
%% but will also supervise the connection between the event handler and the calling process.
add_sup_handler(Handler,Args) ->
gen_event:add_sup_handler(?SERVER,Handler,Args).

%% @doc Deletes an event handler from the event manager:?MODULE
%% The event manager will call Module(Handler):terminate/2 to terminate the event handler.
-spec del_handler(Handler,Args) -> term() | {'EXIT',Reason} | {error,module_not_found} when
Handler::Module | {Module,Id},
Args::term(),
Module::atom(),
Id::term(),
Reason::term().

del_handler(Handler,Args) ->
gen_event:delete_handler(?SERVER,Handler,Args).

%% @doc 异步写入错误信息
notify_error_msg(Msg) ->
gen_event:notify(?SERVER,{update_error_msg,Msg}).

%% @doc 得到文件所有错误日志
sync_notify_error_msg() ->
gen_event:sync_notify(?SERVER,{file_content}).

%% @doc 重新找开储存错误文件:call要指定模块处理
%% 默认timeout 为5000ms
call_open_file() ->
gen_event:call(?SERVER,mod_event_error_msg,{open}).

call_close_file() ->
gen_event:call(?SERVER,mod_event_error_msg,{close},10000).

%% @doc Returns a list of all event handlers installed in the event manager
which_handlers() ->
gen_event:which_handlers(?SERVER).

%%%-------------------------------------------------------------------
%%% @author zhongwencool@gmail.com
%%% @copyright (C) 2014, <COMPANY>
%%% @doc line event
%%%
%%% @end
%%% Created : 20. 二月 2014 下午2:30
%%%-------------------------------------------------------------------
-module(mod_event_error_msg).
-author("zhongwencool@gamil.com").

-behaviour(gen_event).

%% API
%% gen_event callbacks
-export([init/1,
handle_event/2,
handle_call/2,
handle_info/2,
terminate/2,
code_change/3]).

-define(SERVER, ?MODULE).

-record(state, {file_id ,file_name = "error_msg.txt"}).

%%%===================================================================
%%% gen_event callbacks
%%%===================================================================
%%--------------------------------------------------------------------
%% @private
%% @doc
%% Whenever a new event handler is added to an event manager,
%% this function is called to initialize the event handler.
%%
%% @end
%%--------------------------------------------------------------------
-spec(init(InitArgs :: term()) ->
{ok, State :: #state{}} |
{ok, State :: #state{}, hibernate} |
{error, Reason :: term()}).
init(FileName) ->
process_flag(trap_exit, true),
io:format("mod_event_error_msg: init:"),
{ok, Fd} = file:open(FileName, [read, write]),
{ok, #state{file_id = Fd,file_name = FileName}}.

%%--------------------------------------------------------------------
%% @private
%% @doc
%% Whenever an event manager receives an event sent using
%% gen_event:notify/2 or gen_event:sync_notify/2, this function is
%% called for each installed event handler to handle the event.
%%
%% @end
%%--------------------------------------------------------------------
-spec(handle_event(Event :: term(), State :: #state{}) ->
{ok, NewState :: #state{}} |
{ok, NewState :: #state{}, hibernate} |
{swap_handler, Args1 :: term(), NewState :: #state{},
Handler2 :: (atom() | {atom(), Id :: term()}), Args2 :: term()} |
remove_handler).

handle_event(Event, State) ->
NewState = do_handle_event(Event,State),
{ok, NewState}.

%%--------------------------------------------------------------------
%% @private
%% @doc
%% Whenever an event manager receives a request sent using
%% gen_event:call/3,4, this function is called for the specified
%% event handler to handle the request.
%%
%% @end
%%--------------------------------------------------------------------
-spec(handle_call(Request :: term(), State :: #state{}) ->
{ok, Reply :: term(), NewState :: #state{}} |
{ok, Reply :: term(), NewState :: #state{}, hibernate} |
{swap_handler, Reply :: term(), Args1 :: term(), NewState :: #state{},
Handler2 :: (atom() | {atom(), Id :: term()}), Args2 :: term()} |
{remove_handler, Reply :: term()}).
handle_call(Request, State) ->
Reply = ok,
NewState = do_handle_call(Request,State),
{ok, Reply, NewState}.

%%--------------------------------------------------------------------
%% @private
%% @doc
%% This function is called for each installed event handler when
%% an event manager receives any other message than an event or a
%% synchronous request (or a system message).
%%
%% @end
%%--------------------------------------------------------------------
-spec(handle_info(Info :: term(), State :: #state{}) ->
{ok, NewState :: #state{}} |
{ok, NewState :: #state{}, hibernate} |
{swap_handler, Args1 :: term(), NewState :: #state{},
Handler2 :: (atom() | {atom(), Id :: term()}), Args2 :: term()} |
remove_handler).
handle_info(_Info, State) ->
{ok, State}.

%%--------------------------------------------------------------------
%% @private
%% @doc
%% Whenever an event handler is deleted from an event manager, this
%% function is called. It should be the opposite of Module:init/1 and
%% do any necessary cleaning up.
%%
%% @spec terminate(Reason, State) -> void()
%% @end
%%--------------------------------------------------------------------
-spec(terminate(Args :: (term() | {stop, Reason :: term()} | stop |
remove_handler | {error, {'EXIT', Reason :: term()}} |
{error, term()}), State :: term()) -> term()).
terminate(_Arg, _State) ->
io:format("mod_event_line terminate:~p:::State:~p~n",[_Arg,_State]),
ok.

%%--------------------------------------------------------------------
%% @private
%% @doc
%% Convert process state when code is changed
%%
%% @end
%%--------------------------------------------------------------------
-spec(code_change(OldVsn :: term() | {down, term()}, State :: #state{},
Extra :: term()) ->
{ok, NewState :: #state{}}).
code_change(_OldVsn, State, _Extra) ->
{ok, State}.

%%%===================================================================
%%% Internal functions
%%%===================================================================

do_handle_event({update_error_msg,Msg},#state{file_id=Fd} = State) ->
io:format(Fd,"~p~n",[Msg]),
io:format("success write msg to file:~p",[Msg]),
State;

do_handle_event({file_content},#state{file_id=_Fd,file_name = FileName} = State) ->
case file:read_file(FileName) of
{ok,ErrorMsg} -> io:format("file_content:~p~n",[ErrorMsg]);
{error,Reason} -> io:format("file consult error:~p~n",[Reason])
end,
State;

do_handle_event(Msg,#state{file_id=_Fd} = State) ->
io:format("mod_event_error_msg:cannot handler_event this msg :~p",[Msg]),
State.

do_handle_call({open},State = #state{file_id=0,file_name = FileName}) ->
{ok, NewFd} = file:open(FileName, [append,write]),
io:format("open file :~p success~n",[FileName]),
State#state{file_id=NewFd};

do_handle_call({open},State = #state{file_name = FileName}) ->
io:format("file :~p already opened~n",[FileName]),
State;
do_handle_call({close},State = #state{file_id = Fd}) ->
file:close(Fd),
State#state{file_id = 0};

do_handle_call(Msg,State) ->
io:format("mod_event_error_msg:cannot handler_call this msg :~p",[Msg]),
State.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值