When I read Erlang OTP Action book, I found this reminder on page 117:
With your RPC server, you can try calling any function exported from any module available on the server side, except one: your own tr_server:get_count/0. In general, a server can’t call its own API functions. Suppose you make a synchronous call to the same server from within one of the callback functions: for example, if handle_info/2 tries to use the get_count/0 API function. It will then perform a gen_server:call(...) to itself. But that request will be queued up until after the current call to handle_info/2 has finished, resulting in a circular wait—the server is deadlocked.
But I looked at the tr_server sample code :
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.
I found the examples and cautions in the book inconsistent , the gen_server:call and gen_server:cast by tr_server process ownself. Am I misinterpreting this?
1条答案
按热度按时间7gs2gvoe1#
从服务器进程内调用
gen_server:cast
是可以的,因为它是异步的:它将消息添加到进程的邮箱中,然后继续,返回ok
。只有gen_server:call
有这个问题,因为它使进程等待来自自身的应答。