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).

  

原文地址:https://www.cnblogs.com/hanani/p/9981215.html