美文网首页
[Erlang开发之路]二十二、OTP入门

[Erlang开发之路]二十二、OTP入门

作者: 循环不计次 | 来源:发表于2019-07-23 20:55 被阅读0次

    什么是OTP编程?

    可以看作一个用回调函数作为参数的应用程序框架,利用gen_server模块可以实现事物语义和代码热更新,OTP是Open Telecom Platform的缩写,它能帮我们编写大型的、容错的,分布式的系统。刚看这本书的时候,joe大爷说,我们来领悟Erlang中的哲学吧,我寻思又是一些什么奇奇怪怪的东西,其实也就是想向读者表达Erlang的世界观:"一切皆为进程",进程是Erlang的基础设施,不管要完成什么功能,进程都会遵循通用的行为模式,这些进程模式可以称为模式的模式;我们直接使用进程做开发的时候会遵循这个模式,behavior的实现同样遵循进程模式.OTP behaviour包含gen_server gen_event gen_fsm supervisor.其中绝大多数情况下都是在使用gen_server,supervisor本身也是使用gen_server实现的.我们就以gen_server做为起点,逐步学习Erlang OTP.

    1.gen_server模块(OTP中其中一种抽象的编程模式)

    按照joe大爷的脑回路,想要深入学习一门东西并领悟精髓,就是去了解它的原理,去模仿他,类似重构,在这里我就不再把书上的代码贴出来了,我直接把我所理解的gen_server表达出来:

    • 1.事物语义的实现
      什么是事物语义呢?说实话我解释不出来,我只知道书上的代码,会截取抛出的错误,并用错误之前的上下文(书上称是服务器的状态,但我觉得上下文更符合)继续运行软件,也就是服务器时光倒退到了发生错误之前的一刻,而没发生错误的时候,时时刻刻都在更新服务器的上下文。

    • 2.热代码更新的实现
      gen_server模块自带了热更新的功能,Erlang允许程序代码在运行系统中被修改。旧代码能被逐步淘汰而后被新代码替换。在此过渡期间,新旧代码是共存的。

    • 3.gen_server的组成
      在我看来,最主要就是分为:回调函数(handle_call抽象函数的实例化)、接口函数(供用户调用)、启动\停止程序

    handle_call(Recv,From,State)->{reply,Reply,newState}
    %% Recv通常为tag tuple也就是带标签的元组,这样就可以重载多个回调函数,例如{action,A,B}.
    %% State是旧的服务器状态,也就是我说的上下文环境
    %% Reply是我们自定义的返回数据
    %% newState是我们在回调函数中一系列的操作后,变更的上下文环境
    handle_info(Info,State)
    %% 通过这个函数可以接收一些非自发性的消息比如推出信号
    terminate(Reason,State)->ok.
    %% 在收到exit信号或者{stop,Reason,NewState}时会被调用
    code_change(OldVsn,State,Extra)->{ok,NewState}
    %% 在gen_server自动更新代码时被调用
    
    gen_server:start_link({local|global,Name},Mod,[],[])->bool()
    %% local和global的区别是前者在本机可调用,global可跨节点
    %% Name是为进程注册的原子名称
    %% Mod是init([])函数所在的模块名、一般回调和接口函数都在一个模块
    init([])->{ok,State}
    %%gen_server开始start_link的时候会调用init函数来生成一个初始化的服务器上下文环境
    
    gen_server:call(Name,Request)->Reply
    %% 这个函数我们在接口函数会用到,用来远程调用函数
    %% Name是我们start_link的时候注册的名称
    %% Reuqset其实就是handle_call的时候接收的Recv,带标签的元组,往往第一个原子元素就是我们的动作标识,比如写入分数:{setPoint,Who,100}
    %% Reply就是我们在回调函数中的Reply自定义回复数据
    gen_server:cast(Name,Request)->{noreply,State}|...
    %% 这个远程远程调用函数不会接收返回值
    

    一下贴上我自己对gen_server练习的代码:

    -module(otp_server).
    -export([start/0,stop/0,init/1,setPoint/2,deletePoint/1,getPoint/1,handle_call/3,handle_cast/2,handle_info/2,terminate/2,code_change/3]).
    -behaviour(gen_server).
    %                   Server Start
    start()->
            gen_server:start_link({local,?MODULE},?MODULE,[],[]).
    init([])->
            {ok,ets:new(?MODULE,[])}.%Return a new State
    stop()->
            gen_server:call(?MODULE,stop).
    %                   function call
    setPoint(Who,Point)->
            gen_server:call(?MODULE,{set,Who,Point}).
    deletePoint(Who)->
            gen_server:call(?MODULE,{delete,Who}).
    getPoint(Who)->
            gen_server:call(?MODULE,{get,Who}).
    %                   Handle call
    handle_call({set,Who,Point},_From,TableId)->
            ets:insert(TableId,{Who,Point}),
            Reply={Who,set_point_success},
            {reply,Reply,TableId};
    handle_call({delete,Who},_From,TableId)->
            case ets:lookup(TableId,Who) of
                    []->
                            Reply={Who,this_guy_isnot_exist};
                    [_]->
                            Reply=ets:delete(TableId,Who)
            end,
            {reply,Reply,TableId};
    handle_call({get,Who},_From,TableId)->
            case ets:lookup(TableId,Who) of
                    []->
                            Reply={Who,this_guy_isnot_exist};
                    [{Who,Point}]->
                            Reply={Who,point_is,Point}
            end,
            {reply,Reply,TableId};
    handle_call(stop,_From,TableId)->
            {stop,normal,TableId};
    handle_call(_,_From,TableId)->
            {reply,undefine_command,TableId}.
    handle_cast(_Msg,State)->
            {noreply,State}.
    handle_info(_Info,State)->
            {noreply,State}.
    terminate(_Reason,_State)->
            ok.
    code_change(_OldVsn,State,_Extra)->
            {ok,State}.
    

    gen_server的内容绝不会止步于此,明日我会继续更新

    相关文章

      网友评论

          本文标题:[Erlang开发之路]二十二、OTP入门

          本文链接:https://www.haomeiwen.com/subject/kkfzlctx.html