【问题标题】:Returning State from a gen_server cast从 gen_server 演员返回状态
【发布时间】:2017-04-11 17:51:33
【问题描述】:

我正在关注http://learnyousomeerlang.com/static/erlang/kitty_gen_server.erl。

我在 Temple.erl 中有我的应用程序逻辑。所有这些代码都按照我的预期进行了测试和运行。我的land.erl 旨在成为包含神殿的服务器。

我的理解(请纠正任何无知)是我可以使用 gen_server 来抽象消息传递并以最小的开销跟踪状态。

我知道我的 init 函数中的第二个元组值

init([]) -> {ok, temple:new()}. 是我的服务器的状态 - 在这种情况下,temple:new() 的返回值。

所以我c(land)。 (下面的代码),试试这个:

19> {ok, Pid2} = land:start_link().
{ok,<0.108.0>}
20> land:join(Pid2, a).
ok

当我发送加入消息时,我只是得到了原子 ok 通过阅读代码并比较我运行 kitty_gen_server 的经验,我认为状态已正确更新为值 temple:join(Temple, Name),但 ok atom 是响应价值来自

handle_call({join, Name}, _From, Temple) ->
{reply, ok, temple:join(Temple, Name)};

如何使用 Temple:join(Temple, Name) 更新我的状态,然后将此值返回给客户端?我不想调用同一个函数两次,例如。

handle_call({join, Name}, _From, Temple) ->
{reply, temple:join(Temple, Name), temple:join(Temple, Name)};

所以看看我试过的 kitty_gen_server

handle_call({join, Name}, _From, Temple) ->
[{reply, JoinedTemple, JoinedTemple} || JoinedTemple <- temple:join(Temple, Name)];

当我尝试此操作并显示有关语法错误 || 的消息时,我得到一个函数子句崩溃,然后我看到这仅适用于列表推导..

如何计算temple:join(Temple, Name)] 的值并返回到land:join 的调用者并更新Land 的状态?

-module(land).
-behaviour(gen_server).

-export([start_link/0, join/2, input/3, fight/1]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).

start_link() ->
    gen_server:start_link(?MODULE, [], []).

join(Pid, Name) ->
   gen_server:call(Pid, {join, Name}).

input(Pid, Action, Target) ->
    gen_server:call(Pid, {input, Action, Target}).

fight(Pid) ->
    gen_server:call(Pid, fight).

init([]) -> {ok, temple:new()}.

handle_call({join, Name}, _From) ->
  {reply, ok, temple:join(Name)}.
handle_call({join, Name}, _From, Temple) ->
  {reply, temple:join(Temple, Name), temple:join(Temple, Name)};
handle_call(terminate, _From, Temple) ->
    {stop, normal, ok, Temple}.

handle_info(Msg, Temple) ->
    io:format("Unexpected message: ~p~n",[Msg]),
    {noreply, Temple }.

terminate(normal, Temple) ->
    io:format("Temple bathed in blood.~p~n", [Temple]),
    ok.

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

handle_cast(_, Temple) ->
    {noreply, Temple}.

【问题讨论】:

    标签: erlang erlang-otp gen-server


    【解决方案1】:

    您可以将新状态存储在一个变量中,然后返回一个包含该变量的元组两次:

    handle_call({join, Name}, _From, Temple) ->
      NewTemple = temple:join(Temple, Name),
      {reply, NewTemple, NewTemple};
    

    【讨论】:

      猜你喜欢
      • 2019-04-23
      • 2018-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-10
      • 2011-07-04
      • 2011-05-15
      相关资源
      最近更新 更多