一个完整的OTP应用简例

来源:互联网 发布:win10 mac地址修改 编辑:程序博客网 时间:2024/05/23 11:57

    以前研读过一次Erlang OTP框架,但总觉得理解还不够,没有亲手实现一个应用。纸上得来终觉浅,绝知此事须躬行。:)

    近日恰好有时间,又把Erlang OTP框架拿来研读,并尝试完成了一个简单的用OTP实现的应用。本应用同时实现了一个事件管理器及相关测试代码。

    应用实例中实现的行为模式包括application、supervisor、gen_server、gen_event,实现的简单功能是定制事件管理器来实现事件日志,可以添加和删除事件管理器,并使用自定义的事件管理器输出事件日志,使用应用来启动监督进程,利用监督进程管理普通服务器和事件管理器的进程。

    应用实例的主要模块包括:event_app(实现application)、root_sup(实现supervisor)、myserv(实现gen_server)、event_mod(实现gen_event)。应用的目录结构也采取最简单的形式,即项目主目录下仅有两个子目录:ebin 和 src。

    其基本代码如下:

%filename event_app.app%应用资源文件{application, event_app,[{description,"a simple logger."},{vsn,"1.0"},{modules,[event_mod,root_sup,event_app,myserv]},{registered,[event_mod,root_sup,myserv]},{applications,[kernel,stdlib]},{mod,{event_app,[]}}]}.     %%指明应用启动模块

%filename event_app.erl-module (event_app).-behaviour (application).  %%实现应用行为-compile(export_all).start(_Type,_StartArgs) ->    case root_sup:start_link() of        {ok,Pid} -> {ok,Pid};        Other ->            {error,Other}    end.stop(_State) -> ok.

%filename root_sup-module (root_sup).-behaviour (supervisor).  %%实现监督者行为-compile(export_all).start_link() ->    supervisor:start_link({local,?MODULE},?MODULE,[]).init([]) ->    Event = {event_mod,{event_mod,start_link,[]},        permanent,2000,worker,[event_mod]},    Myserv = {myserv,{myserv,start_link,[]},        permanent,2000,worker,[myserv]},    Children = [Event,Myserv],    RestartStrategy = {one_for_one,0,1},    {ok,{RestartStrategy,Children}}.      %%返回监控进程规范和子进程规范列表
%filename myserv.erl-module (myserv).-behaviour (gen_server).-compile(export_all).start_link() ->    gen_server:start_link({local,?MODULE},?MODULE,[],[]).init([]) ->{ok,[]}.add_hdl() ->       %%添加自定义事件处理器(用户API)    gen_server:cast(?MODULE,addhdl).del_hdl() ->       %%删除自定义事件处理器(用户API)    gen_server:cast(?MODULE,delhdl).log_test() ->      %%引发日志事件测试    event_mod:log_test().  %%通过调用委托给event_mod模块handle_cast(addhdl,State) ->    event_mod:add_handler(),   %%通过调用委托给event_mod模块    {noreply,State};handle_cast(delhdl,State) ->    event_mod:del_handler(),   %%通过调用委托给event_mod模块    {noreply,State}.%%其它消息不作处理handle_call(_,_,State) -> {reply,{ok,ok},State}.handle_info(_,State) -> {noreply,State}.code_change(_OldVsn,State,_Extra) -> {ok,State}.terminate(_,_) -> ok.

%filename event_mod.erl-module (event_mod).-compile(export_all).-behaviour (gen_event).   %%实现事件管理器行为start_link() ->    gen_event:start_link({local,?MODULE}).init([]) -> {ok,[]}.add_handler() ->          %%添加事件管理器    gen_event:add_handler(?MODULE,?MODULE,[]).delete_handler() ->       %%删除事件管理器    gen_event:delete_handler(?MODULE,?MODULE,[]).log_test() ->             %%引发日志事件测试函数    gen_event:notify(?MODULE,test).  %%引发日志事件handle_event(test,State) ->          %%引发日志事件的处理函数    error_logger:info_msg("Test send up.~n"),    {ok,File} = file:open("aqw.txt",write),  %%可将相关日志信息写入指定文件,实际程序中文件名不会硬编码    io:format(File,"aqwkdkkdkd~n",[]),    file:close(File),    {ok,State};handle_event(_Msg,State) ->    {ok,State}.

运行测试结果如下图:


原创粉丝点击