在handle_call/3行为(gen_server),Erlang/OTP的递归调用中出现超时错误

Ale*_*rut 1 erlang recursion erlang-otp gen-server

我正在尝试在回复之前对handle_call/3进行递归调用.但似乎不可能,因为timeout抛出了退出异常.您可以在下面看到代码和错误.

代码:

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

%% API
-export([start_link/0,init/1,handle_info/2,first_call/1,second_call/1, handle_call/3, terminate/2]).

-record(state, {whatever}).

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

init(_Args) ->
  {ok, #state{}}.

handle_info(Data, State) ->
  {noreply, State}.

% synchronous messages
handle_call(_Request, _From, State) ->
  case _Request of
    first_call ->
      {reply, data1, State};
    second_call ->
      {reply, {data2, first_call(self())}, State}
  end.

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

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

terminate(_Reason, _State) ->
  ok.
Run Code Online (Sandbox Code Playgroud)

错误:

2> {_, PID} = test:start_link().
{ok,<0.64.0>}
3> test:second_call(PID).
** exception exit: {timeout,{gen_server,call,[<0.64.0>,second_call]}}
     in function  gen_server:call/2 (gen_server.erl, line 204) 
Run Code Online (Sandbox Code Playgroud)

这种行为的一个可能原因是gen_server在完成第一个调用之前无法处理递归调用(创建死锁).这是正确的理由,如果是,为什么?谢谢.

leg*_*cia 6

是的,这就是原因.gen_server是一个进程,在handle_call执行时它不会接收任何消息也不响应任何消息gen_server:call.因此first_call(self())超时.