介绍gen_server的示例代码

OTPopen telecomplatform),它的设计目标是用于做一套容错系统。最核心的概念就是behavior。类似类继承,在类里编写函数实现;而外层非应用逻辑相关的东西(热更新,监控机制等等)交OTP体系来控制。

先介绍gen_server模块。使用这个编写服务器只需要确认这3件事情:

1.      确定一个回调模块的名称;

2.      写接口函数;

3.      在回调模块中写需要的6个函数;

下面这个例子代码摘自《Erlang程序设计》16章。

代码: 

%%
%% Author:  erlang.hell
%% Date:    2012-11-18
%%

-module(my_bank).
-behavior(gen_server).
-export([start/0,stop/0,new_account/1,deposit/2,withdraw/2,
        init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

%%====================================================================
%% server interface function
%%====================================================================
start()->
    gen_server:start_link({local,?MODULE}, ?MODULE,[],[]).

stop()->
    gen_server:call(?MODULE,stop).

new_account(Who)->
    gen_server:call(?MODULE,{new,Who}).

deposit(Who,Amount)->
    gen_server:call(?MODULE,{add,Who,Amount}).

withdraw(Who,Amount)->
    gen_server:call(?MODULE,{remove,Who,Amount}).

%%====================================================================
%% gen_server callbacks
%%====================================================================
init([]) ->
    Init=ets:new(?MODULE,[]),
    io:format("init ~p ~p",[Init,?MODULE]),
    {ok, Init}.

handle_call({new,Who}, _From, State) ->
    Reply = case ets:lookup(State,Who) of
        []->ets:insert(State,{Who,0}),
            {welcome,Who};
        [_]->{exsits,Who,you_already_are_a_customer}
    end,
    {reply, Reply, State}; 
handle_call({add,Who,Amount},_From,State)->
    Reply = case ets:lookup(State,Who) of
        []->not_a_customer;
        [{Who,Balance}]->
            NewBalance=Balance+Amount,
            ets:insert(State,{Who,NewBalance}),
            {thanks,Who,you_balance_is,NewBalance}
    end,
    {reply, Reply, State}; 
handle_call({remove,Who,Amount},_From,State)->
    Reply = case ets:lookup(State,Who) of
        []->not_a_customer;
        [{Who,Balance}] when Amount =< Balance ->
            NewBalance=Balance-Amount,
            ets:insert(State,{Who,NewBalance}),
            {thanks,Who,your_balance_is,NewBalance};
        [{Who,Balance}]->
            {sorry,Who,you_only_have,Balance,in_the_bank}
    end,
    {reply, Reply, State}.

handle_cast(_Msg, State) ->
    {noreply, State}.

handle_info(_Info, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
    io:format("is terminate.",[]),
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.


 

测试:

Eshell V5.9.1  (abort with ^G)

9>my_bank:new_account("erlang").

{welcome,"erlang"}

10>my_bank:deposit("erlang",10).

{thanks,"erlang",you_balance_is,10}

11>my_bank:deposit("erlang",20).

{thanks,"erlang",you_balance_is,30}

12> my_bank:withdraw("erlang",5).

{thanks,"erlang",your_balance_is,25}

 

遇到的麻烦:

4>my_bank:new_account("erlang",100).

** exception error: undefined functionmy_bank:new_account/2

5>my_bank:new_account("erlang").   

** exception exit:{noproc,{gen_server,call,[my_bank,{new,"erlang"}]}}

    in function  gen_server:call/2(gen_server.erl, line 180)

6>my_bank:deposit("erlang",10).

** exception exit:{noproc,{gen_server,call,[my_bank,{add,"erlang",10}]}}

    in function  gen_server:call/2(gen_server.erl, line 180)

在第4步的时候,我输入了2个参数,造成异常;后面即使输入正常了,但是这个gen_server已经没有工作;这种情况下就会爆出这样的错误。{noproc,{gen_server,call,…;遇到这个问题就需要再次调用my_bank:start()函数,将server启动起来。

 

掌握的知识点:

1.      OPT基本回调框架:

它存在6个回调函数函数,在模块起始的地方定义behavior自于gen_server

State这个是贯穿于gen_server体系的回调函数;在每次回调都有权利修改他。Init函数用于生产出一个这样的tuple出来,handle函数用于加工;terminate的时候由于收场。

2.      基础语法:

函数覆盖的时候是使用“;”。如new,add,remove 3个方法是互为补充;我们就不能再每个函数后面写“.”。

使用cast语句来做条件分支:

cast ets:lookup( Table, Key ) of

[]->not_find;

[{ Who , Balance }] when Balance =< XXX ->

NewBalance=Balance-XXX,

ets:insert(Table,{Who,NewBalance},

{thinks};

[{Who,_}] ->

   {sorry,not_enough_money}.

3.      熟悉ets相关知识:

构建一个ets出来

ets:new(?MODULE,[]).

ets中检索

ets:lookup(TBL,KEY).

插入ets

ets:insert(TBL,{KEY,VAL}).

 

佛法无边。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值