aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2016-03-11 13:13:59 +0100
committerBjörn Gustavsson <[email protected]>2016-03-11 14:41:55 +0100
commitcccf762d93640b707f8e1515604cebcfbe379c04 (patch)
tree2c9ccb69330dc490ccb9970bdf79861a6512d411 /lib/kernel
parente0bb95ed1e7e1314697b51d10ae59cd09c557941 (diff)
downloadotp-cccf762d93640b707f8e1515604cebcfbe379c04.tar.gz
otp-cccf762d93640b707f8e1515604cebcfbe379c04.tar.bz2
otp-cccf762d93640b707f8e1515604cebcfbe379c04.zip
Don't throw exceptions from rpc:call() and rpc:block_call()
The documentation for rpc:call() says: Evaluates apply(Module, Function, Args) on the node Node and returns the corresponding value Res, or {badrpc, Reason} if the call fails. What is not said that rpc:call() can generate an exception if the 'rex' process on the other node is killed: (kalle@host)1> Rex = rpc:call(arne@host, erlang, whereis, [rex]). <6937.14.0> (kalle@host)2> rpc:call(arne@host, erlang, exit, [Rex,kill]). ** exception exit: {killed, {gen_server,call, [{rex,arne@host}, {call,erlang,exit,[<6937.14.0>,kill],<0.33.0>}, infinity]}} in function rpc:rpc_check/1 (rpc.erl, line 361) On the other hand, if the other node shuts down for some other reason, we'll get a {badrpc,nodedown} result: (kalle@host)5> rpc:call(arne@host, erlang, halt, []). {badrpc,nodedown} There does not seem to be any reason to handle the two cases differently. If the 'rex' process is terminated on the other node, it will shut down shortly thereafter. Therefore, change rpc:call() and rpc:block_call() to always return {badrpc,Reason} is the call fails: (kalle@host)1> Rex = rpc:call(arne@host, erlang, whereis, [rex]). <6937.14.0> (kalle@host)2> rpc:call(arne@host, erlang, exit, [Rex,kill]). {badrpc,{'EXIT',{killed,{gen_server,call, [{rex,arne@host}, {call,erlang,exit,[<7126.14.0>,kill],<0.33.0>}, infinity]}}}}
Diffstat (limited to 'lib/kernel')
-rw-r--r--lib/kernel/src/rpc.erl8
-rw-r--r--lib/kernel/test/rpc_SUITE.erl26
2 files changed, 17 insertions, 17 deletions
diff --git a/lib/kernel/src/rpc.erl b/lib/kernel/src/rpc.erl
index d3db8eb80a..b9284487d2 100644
--- a/lib/kernel/src/rpc.erl
+++ b/lib/kernel/src/rpc.erl
@@ -357,8 +357,12 @@ do_call(Node, Request, Timeout) ->
rpc_check_t({'EXIT', {timeout,_}}) -> {badrpc, timeout};
rpc_check_t(X) -> rpc_check(X).
-rpc_check({'EXIT', {{nodedown,_},_}}) -> {badrpc, nodedown};
-rpc_check({'EXIT', X}) -> exit(X);
+rpc_check({'EXIT', {{nodedown,_},_}}) ->
+ {badrpc, nodedown};
+rpc_check({'EXIT', _}=Exit) ->
+ %% Should only happen if the rex process on the other node
+ %% died.
+ {badrpc, Exit};
rpc_check(X) -> X.
diff --git a/lib/kernel/test/rpc_SUITE.erl b/lib/kernel/test/rpc_SUITE.erl
index 0e9068fa2b..101cff7ed2 100644
--- a/lib/kernel/test/rpc_SUITE.erl
+++ b/lib/kernel/test/rpc_SUITE.erl
@@ -350,34 +350,30 @@ called_node_dies(Config) when is_list(Config) ->
PA = filename:dirname(code:which(?MODULE)),
node_rep(
- fun (Tag, Call, Args) ->
- {Tag,{badrpc,nodedown}} =
- {Tag,apply(rpc, Call, Args)}
+ fun (Call, Args) ->
+ {badrpc,nodedown} = apply(rpc, Call, Args)
end, "rpc_SUITE_called_node_dies_1",
PA, ?MODULE, suicide, [erlang,halt,[]]),
node_rep(
- fun (Tag, Call, Args) ->
- {Tag,{badrpc,nodedown}} =
- {Tag,apply(rpc, Call, Args)}
+ fun (Call, Args) ->
+ {badrpc,nodedown} = apply(rpc, Call, Args)
end, "rpc_SUITE_called_node_dies_2",
PA, ?MODULE, suicide, [init,stop,[]]),
node_rep(
- fun (Tag, Call, Args=[_|_]) ->
- {Tag,{'EXIT',{killed,_}}} =
- {Tag,catch {noexit,apply(rpc, Call, Args)}}
+ fun (Call, Args=[_|_]) ->
+ {badrpc,{'EXIT',{killed,_}}} = apply(rpc, Call, Args)
end, "rpc_SUITE_called_node_dies_3",
PA, ?MODULE, suicide, [erlang,exit,[rex,kill]]),
node_rep(
- fun (_Tag, block_call, _Args) ->
+ fun (block_call, _Args) ->
%% Cannot block call rpc - will hang
ok;
- (Tag, Call, Args=[_|_]) ->
- {Tag,{'EXIT',{normal,_}}} =
- {Tag,catch {noexit,apply(rpc, Call, Args)}}
- end, "rpc_SUITE_called_node_dies_4",
+ (Call, Args=[_|_]) ->
+ {badrpc,{'EXIT',{normal,_}}} = apply(rpc, Call, Args)
+ end, "rpc_SUITE_called_node_dies_4",
PA, ?MODULE, suicide, [rpc,stop,[]]),
ok.
@@ -392,7 +388,7 @@ node_rep_call(Tag, Call, Args, Fun, Name0, PA) ->
Name = list_to_atom(Name0 ++ "_" ++ atom_to_list(Tag)),
{ok, N} = test_server:start_node(Name, slave,
[{args, "-pa " ++ PA}]),
- Fun(Tag, Call, [N|Args]),
+ Fun(Call, [N|Args]),
catch test_server:stop_node(N),
ok.