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

什么是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的内容绝不会止步于此,明日我会继续更新

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354