Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
erlang gen_server bank_account
%%%-------------------------------------------------------------------
%%% @author Suncle
%%% @copyright (C) 2017, <COMPANY>
%%% @doc
%%% @end
%%% Created : 13. 十一月 2017 17:19
%%%-------------------------------------------------------------------
-module(bank_account).
-author("Suncle").
-behaviour(gen_server).
%% 回调接口
-export([init/1,
handle_call/3,
handle_cast/2,
handle_info/2,
code_change/3,
terminate/2
]).
%% API
-export([start_link/3,
withdraw/2,
deposit/2,
print/1,
stop/1]).
-record(account,{
id :: integer(), %% ID
name :: string(), %% 帐号名
money :: integer() %% 帐号余额
}).
-define(PRINT(Msg),io:format(Msg ++ "\n")).
-define(PRINT(Format,Msg),io:format(Format ++ "\n",Msg)).
init([Id, Name, Money]) ->
?PRINT("bank account init,ID:~w,Name:~p,Money:~w",[Id,Name,Money]),
State = #account{id = Id, name = Name, money = Money},
{ok,State}.
%% asynchronous operation
%% handle_cast接收gen_server:cast消息
%% 打印帐号信息
handle_cast(print, State = #account{id = Id, name = Name, money = Money}) ->
?PRINT("account info, id: ~w, name: ~p, money: ~w", [Id, Name, Money]),
{noreply, State};
%% 返回stop,进程将停止,调用terminate
handle_cast(stop, State) ->
?PRINT("handle cast stop"),
{stop, normal, State}.
%% synchronous operation
%% handle_call接收gen_server:call消息
%% 取款
handle_call({withdraw, Num}, _From, State = #account{name = Name,money = Money}) when Num > 0, Num =< Money ->
NewMoney = Money - Num,
NewState = State#account{money = NewMoney},
?PRINT("~p withdraw:~w,NewMoney:~w",[Name, Num, NewMoney]),
{reply, true, NewState};
%% 存款
handle_call({deposit, Num}, _From, State = #account{name = Name,money = Money}) ->
NewMoney = Money + Num,
NewState = State#account{money = NewMoney},
?PRINT("~p withdraw:~w,NewMoney:~w",[Name, Num, NewMoney]),
{reply, true, NewState}.
%% handle_info,处理直接发给进程的消息
handle_info(Info, State) ->
?PRINT("handle_info receive msg:~p",[Info]),
{noreply,State}.
code_change(_OldVsn, State, _Extra) ->
{ok,State}.
%% 进程停止时,回调terminate
terminate(Reason, #account{id = ID,name = Name,money = Money}) ->
?PRINT("process stop,Reason:~p",[Reason]),
?PRINT("account Info,ID:~w,Name:~p,Money:~w",[ID,Name,Money]),
ok.
%% 开启帐号进程,将回调init/1函数,返回{ok,Pid}
start_link(Id, Name, Money) ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [Id, Name, Money], []).
withdraw(Pid,Num) ->
gen_server:call(Pid,{withdraw,Num}).
deposit(Pid,Num) ->
gen_server:call(Pid,{deposit,Num}).
print(Pid) ->
gen_server:cast(Pid,print).
stop(Pid) ->
gen_server:cast(Pid,stop).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.