diff options
author | Adam Kocoloski <adam@cloudant.com> | 2013-11-22 15:58:02 -0500 |
---|---|---|
committer | Robert Newson <rnewson@apache.org> | 2014-07-23 18:03:23 +0100 |
commit | 8f9d160c688af025179b0f61be972a00b33f5fad (patch) | |
tree | bb1e025579e84e8d3b17f2820fe648eb1722141e | |
parent | 664f0b8f3f42f43be87aa9687372bac96c7743a0 (diff) | |
download | couchdb-8f9d160c688af025179b0f61be972a00b33f5fad.tar.gz |
Don't block the governor to send a message
This allows the governor to continue prioritizing incoming requests
instead of hanging for several seconds to try to connect to the remote
node.
BugzID: 23717
BugzID: 23718
-rw-r--r-- | src/rexi_governor.erl | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/src/rexi_governor.erl b/src/rexi_governor.erl index fdf8c93b2..12ec013ce 100644 --- a/src/rexi_governor.erl +++ b/src/rexi_governor.erl @@ -25,6 +25,7 @@ -record(state, { buffer = queue:new(), + sender = nil, count = 0 }). @@ -55,19 +56,30 @@ handle_cast({deliver, Dest, Msg}, #state{buffer = Q, count = C} = State) -> {noreply, State#state{buffer = Q2, count = C+1}, 0} end. -handle_info(timeout, State) -> +handle_info(timeout, #state{sender = nil} = State) -> #state{buffer = Q, count = C} = State, - case queue:out_r(Q) of + Sender = case queue:out_r(Q) of {{value, {Dest, Msg}}, Q2} -> - erlang:send(Dest, Msg); + case erlang:send(Dest, Msg, [noconnect, nosuspend]) of + ok -> + nil; + _Else -> + spawn_monitor(erlang, send, [Dest, Msg]) + end; {empty, Q2} -> - ok + nil end, - if C > 1 -> + if Sender =:= nil, C > 1 -> {noreply, State#state{buffer = Q2, count = C-1}, 0}; true -> - {noreply, State#state{buffer = Q2, count = 0}} - end. + {noreply, State#state{buffer = Q2, sender = Sender, count = C-1}} + end; +handle_info(timeout, State) -> + % Waiting on a sender to return + {noreply, State}; + +handle_info({'DOWN', Ref, _, Pid, _}, #state{sender = {Pid, Ref}} = State) -> + {noreply, State#state{sender = nil}, 0}. terminate(_Reason, _State) -> ok. |