问题
i created 2 erlang nodes in the same Windows machine with two cmd windows:'unclient@MYPC' and 'unserveur@MYPC' , the server code is very simple :
-module(serveur).
-export([start/0,recever/0,inverse/1]).
%%%%
start() ->
process_flag(trap_exit,true),
Pid=spawn_link(serveur,recever,[]),
register(ownServer, Pid).
%%%%
recever() ->
receive
{From, X} ->From ! {ownServer,1/X}
end.
%%%%
inverse(X) ->
ownServer!{self(), X},
receive
{'EXIT',_, _} ->start(),
sorry;
{ownServer, Reply} ->Reply
end.
so at the server node cmd i start this module
c(serveur).
serveur:start().
and i tested this server :at the server node cmd i used :
apply(serveur,inverse,[2]).
and i received 0.5 and i tried too causing an error by using an atom in the place of a number :
apply(serveur,inverse,[a]).
and the shell shows the error and shows 'sorry' and the server returns to its work correctly by restarting his child automatically because it is a system process and he traps the exit of his child.
now at the client node i used the rpc call function to try the connection and all is fine, for example i try :
rpc:call('unserveur@MYPC' ,serveur,inverse,[2]).
and at the client node cmd i receive :0.5
now i use an atom to send it to the server for causing an error
rpc:call('unserveur@MYPC' ,serveur,inverse,[a]).
at the client cmd node : i waited for the response from the server that should be 'sorry' but i didn't receive anything and there is no more the client prompt :
unclient@MYPC 1>
i can write but the shell does not execute my instructions anymore and there is not any prompt. at the server node : i see an error and then the server prompt returns normally
unserveur@MYPC 5>
i tried this at the server node prompt :
apply(serveur, inverse, [2]).
and i had an error, so i restart the server manually by calling the start() function at the server node cmd and after that the server returns to work normally. I tried self() on the server node cmd before and after the client call and the pid is the same and this is logic because the main server process is a system process so my result that he didn't execute the code after receive {'EXIT',...}. why that happens ? i couldn't understand this bug so any one can explain to me please what that happens ?
回答1:
This happens because the EXIT
message is sent to any process that is linked to the server process, which is not necessarily the same process that sent the message.
It works when you run it in the shell, since the shell process gets linked to the server process, and the shell process is also the one that calls the inverse
function. However, when you make an RPC call, the inverse
function is called from a different process.
Try making the RPC call from the client, and then running flush().
in the shell of the server node, and you should see the EXIT
message.
来源:https://stackoverflow.com/questions/62308147/a-bug-in-erlang-node-after-an-error-at-another-node