Don't block rexi_server to send a message
When a worker dies rexi_server needs to notify the remote client. If
communication to the remote node is impaired rexi_server may block for
several seconds trying to send the rexi_EXIT message.
Fix is to use the same 'noconnect' and 'nosuspend' options in
rexi_server that we use to submit jobs from a client.
BugzID: 13298
diff --git a/src/rexi.erl b/src/rexi.erl
index a98b561..bf1c2ab 100644
--- a/src/rexi.erl
+++ b/src/rexi.erl
@@ -59,14 +59,15 @@
-spec cast(node(), pid(), {atom(), atom(), list()}) -> reference().
cast(Node, Caller, MFA) ->
Ref = make_ref(),
- do_send({?SERVER, Node}, cast_msg({doit, {Caller, Ref}, get(nonce), MFA})),
+ Msg = cast_msg({doit, {Caller, Ref}, get(nonce), MFA}),
+ rexi_utils:send({?SERVER, Node}, Msg),
Ref.
%% @doc Sends an async kill signal to the remote process associated with Ref.
%% No rexi_EXIT message will be sent.
-spec kill(node(), reference()) -> ok.
kill(Node, Ref) ->
- do_send({?SERVER, Node}, cast_msg({kill, Ref})),
+ rexi_utils:send({?SERVER, Node}, cast_msg({kill, Ref})),
ok.
%% @equiv async_server_call(Server, self(), Request)
@@ -82,7 +83,7 @@
-spec async_server_call(pid() | {atom(),node()}, pid(), any()) -> reference().
async_server_call(Server, Caller, Request) ->
Ref = make_ref(),
- do_send(Server, {'$gen_call', {Caller,Ref}, Request}),
+ rexi_utils:send(Server, {'$gen_call', {Caller,Ref}, Request}),
Ref.
%% @doc convenience function to reply to the original rexi Caller.
@@ -112,14 +113,3 @@
%% internal functions %%
cast_msg(Msg) -> {'$gen_cast', Msg}.
-
-% send a message as quickly as possible
-do_send(Dest, Msg) ->
- case erlang:send(Dest, Msg, [noconnect, nosuspend]) of
- noconnect ->
- spawn(erlang, send, [Dest, Msg]);
- nosuspend ->
- spawn(erlang, send, [Dest, Msg]);
- ok ->
- ok
- end.
diff --git a/src/rexi_server.erl b/src/rexi_server.erl
index aa417aa..dd19248 100644
--- a/src/rexi_server.erl
+++ b/src/rexi_server.erl
@@ -187,4 +187,4 @@
case ets:lookup(Tab, Ref) of [] -> false; [Worker] -> Worker end.
notify_caller({Caller, Ref}, Reason) ->
- Caller ! {Ref, {rexi_EXIT, Reason}}.
+ rexi_utils:send(Caller, {Ref, {rexi_EXIT, Reason}}).
diff --git a/src/rexi_utils.erl b/src/rexi_utils.erl
index 7791866..721877e 100644
--- a/src/rexi_utils.erl
+++ b/src/rexi_utils.erl
@@ -1,6 +1,17 @@
-module(rexi_utils).
--export([recv/6]).
+-export([send/2, recv/6]).
+
+%% @doc send a message as quickly as possible
+send(Dest, Msg) ->
+ case erlang:send(Dest, Msg, [noconnect, nosuspend]) of
+ noconnect ->
+ spawn(erlang, send, [Dest, Msg]);
+ nosuspend ->
+ spawn(erlang, send, [Dest, Msg]);
+ ok ->
+ ok
+ end.
%% @doc set up the receive loop with an overall timeout
-spec recv([any()], integer(), function(), any(), timeout(), timeout()) ->