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

knsnq2tg  于 2022-12-08  发布在  Erlang
关注(0)|答案(1)|浏览(188)

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?

7gs2gvoe

7gs2gvoe1#

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

相关问题