【问题标题】:Why does my gen_server implementation give a timeout?为什么我的 gen_server 实现会超时?
【发布时间】:2016-06-28 02:37:00
【问题描述】:

我正在尝试学习 Erlang 和 OTP,因此我目前正在尝试处理 gen_server

我写了一个快速的 gen_server 实现:

-module(test).
-behavior(gen_server).

%% API
-export([start/0, add/1]).
-export([init/1, terminate/2, code_change/3, handle_call/3, handle_cast/2, handle_info/2]).

start() -> gen_server:start_link(?MODULE, [], []).
add(Value) -> gen_server:call(self(), {add, Value}).

%% Gen_Server
init(_Arguments) ->  {ok, []}.
terminate(_Reason, _State) -> ok.
code_change(_PreviousVersion, State, _) -> {ok, State}.

handle_call({add, Value}, _From, State) -> {reply, ok, [Value|State]}.
handle_cast(_Arg0, State) ->  {noreply, State}.
handle_info(Info, State) -> io:format("Unexpected message: ~p~n",[Info]), {noreply, State}.

问题在于 add/1 调用超时而不是返回 ok:

1> {ok, Pid} = test:start().
{ok,<0.33.0>}
2> Pid ! abc.
Unexpected message: abc
abc
3> test:add(3).
** exception exit: {timeout,{gen_server,call,[<0.31.0>,{add,3}]}}
     in function  gen_server:call/2 (gen_server.erl, line 204)
4> Pid ! abc.
abc

我做错了什么?当我运行 gen_server:call/2 时,服务器似乎不再运行。

【问题讨论】:

    标签: erlang erlang-otp gen-server


    【解决方案1】:

    您传入self() 作为test:add 中gen_server 的pid,这是不正确的。 self() 将评估为您在调用时所在的 REPL 进程的 pid。

    您可以简单地将 gen_server pid 作为参数添加到 test:add,因为它是从 test:start() 获取的。

    【讨论】:

    • 为什么这么糟糕?我不希望 REPL 接收来自 gen_server 的回复,以便我可以验证 REPL 中的回复吗?
    • 哦,我明白了,我完全误解了gen_server:call/2的第一个参数是什么!我误解了 LYSE 中从非gen_servergen_server 章节的切换。
    猜你喜欢
    • 2020-08-20
    • 2016-05-28
    • 2022-11-25
    • 1970-01-01
    • 2012-09-18
    • 2021-09-30
    • 1970-01-01
    • 1970-01-01
    • 2012-08-14
    相关资源
    最近更新 更多