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

1 erlang erlang-otp gen-server erlang-supervisor

当我阅读《Erlang OTP Action》一书时,我在第 117 页发现了这样的提醒:

\n

使用 RPC 服务器,您可以尝试调用从服务器端可用的任何模块导出的任何函数,除了一个:您自己的 tr_server:get_count/0。一般来说,服务器不能调用自己的API函数。假设您从回调函数之一对同一服务器进行同步调用:例如,如果handle_info/2 尝试使用get_count/0 API 函数。然后它将对其自身执行 gen_server:call(...) 。但是该请求将排队直到当前对handle_info/2的调用完成之后,导致循环wait\xe2\x80\x94服务器陷入死锁。

\n

但我查看了 tr_server 示例代码:

\n
get_count() ->\n    gen_server:call(?SERVER, get_count).   \n\nstop() ->\n    gen_server:cast(?SERVER, stop).\n\nhandle_info({tcp, Socket, RawData}, State) ->                   \n    do_rpc(Socket, RawData),\n    RequestCount = State#state.request_count,\n    {noreply, State#state{request_count = RequestCount + 1}};\n......\ndo_rpc(Socket, RawData) ->\ntry\n    {M, F, A} = split_out_mfa(RawData),\n    Result = apply(M, F, A),  %  tr_server process -> handle_info -> do_rpc ->call & cast                                \n    gen_tcp:send(Socket, io_lib:fwrite("~p~n", [Result]))       \ncatch\n    _Class:Err ->\n        gen_tcp:send(Socket, io_lib:fwrite("~p~n", [Err]))\nend.\n
Run Code Online (Sandbox Code Playgroud)\n

我发现书中的示例和注意事项不一致,tr_server 进程自己的 gen_server:call 和 gen_server:cast。\n我是否误解了这一点?

\n

leg*_*cia 6

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