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
有这个问题,因为它让进程等待自己的回答。
当我阅读 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
有这个问题,因为它让进程等待自己的回答。