Erlang练习2:火烈鸟
使用genserver实现进程间通讯,名曰:Flamingo!
-module(flamingo).
-behaviour(gen_server).
%% API
-export([new/1,route/4,request/4]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
%%%===================================================================
%%% API
%%%===================================================================
new(Global) -> gen_server:start(?MODULE, Global, []).
route(Flamingo, Prefixes, Action, Arg) -> gen_server:call(Flamingo, {route, {Prefixes, Action, Arg}}).
request(Flamingo, Request, From, Ref) -> gen_server:cast(Flamingo, {request, {Request, From, Ref}}).
%%%===================================================================
%%% gen_server callbacks
%%%===================================================================
init(Global) -> {ok, {Global,#{}}}.
handle_call({route, {Prefixes, Action, Arg}}, From, State) ->
{Global,GlobalIniti} = State,
case Action:initialise(Arg) of
{ok,LocalState} -> NewGlobalIniti = assign_Action(Prefixes,{Action,LocalState},GlobalIniti),
{reply, {ok,From},{Global,NewGlobalIniti}};
_ -> {reply, {error,module_could_not_be_initialised}, State}
end.
handle_cast({request, {Request, From, Ref}}, State) ->
{Name, _} = Request,
{Global,GlobalIniti} = State,
case maps:find(Name,GlobalIniti) of
{ok,{Action,LocalState}} ->
case Action:action(Request, Global, LocalState) of
{_,Content,_} -> From ! {Ref,{200,Content}},
{noreply, State};
{_,Content} -> From ! {Ref, {202,Content}},
{noreply, State};
_ -> From ! {Ref, {500,action_fails}},
{noreply, State}
end;
error -> From ! {Ref,{404, not_match}},
{noreply, State}
end.
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%%%===================================================================
%%% Internal functions
%%%===================================================================
assign_Action([],_,GlobalIniti) -> GlobalIniti;
assign_Action([P|Prefixes],Action,GlobalIniti) ->
NewGlobalIniti = maps:put(P ,Action,GlobalIniti),
assign_Action(Prefixes,Action,NewGlobalIniti).

浙公网安备 33010602011771号