gen_server , 服务器不能调用自己的 API 函数?

gen_server , a server can’t call its own API functions?

当我阅读 Erlang OTP Action 书时,我在第 117 页发现了这个提醒:

使用您的 RPC 服务器,您可以尝试调用从服务器端可用的任何模块导出的任何函数,除了一个:您自己的 tr_server:get_count/0。通常,服务器无法调用自己的 API 函数。 假设您从其中一个回调函数中对同一服务器进行同步调用:例如,if handle_info/2 尝试使用 get_count/0 API 函数。然后它将对自己执行 gen_server:call(...) 。但是该请求将排队等待当前对 handle_info/2 的调用完成,从而导致循环等待——服务器死锁。

但我查看了 tr_server 示例代码:

get_count() ->
    gen_server:call(?SERVER, get_count).   

stop() ->
    gen_server:cast(?SERVER, stop).

handle_info({tcp, Socket, RawData}, State) ->                   
    do_rpc(Socket, RawData),
    RequestCount = State#state.request_count,
    {noreply, State#state{request_count = RequestCount + 1}};
......
do_rpc(Socket, RawData) ->
try
    {M, F, A} = split_out_mfa(RawData),
    Result = apply(M, F, A),  %  tr_server process -> handle_info -> do_rpc ->call & cast                                
    gen_tcp:send(Socket, io_lib:fwrite("~p~n", [Result]))       
catch
    _Class:Err ->
        gen_tcp:send(Socket, io_lib:fwrite("~p~n", [Err]))
end.

我发现书中的例子和注意事项不一致,gen_server:call和gen_server:cast由tr_server过程自己完成。 我是不是误解了这个?

从服务器进程内部调用 gen_server:cast 没问题,因为它是异步的:它将消息添加到进程的邮箱中,然后继续,返回 ok。只有gen_server:call有这个问题,因为它让进程等待自己的回答。