summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Radestock <matthias@rabbitmq.com>2014-04-13 19:45:06 +0100
committerMatthias Radestock <matthias@rabbitmq.com>2014-04-13 19:45:06 +0100
commit3a3b67e62ad22ddb7d0eedb2a93d1bcf247d26bf (patch)
tree1209dbfa8083b28b2467791085b3b7c13abdf7bb
parent81986c4e315d9e58dad74a470b262ba7feb84b37 (diff)
downloadrabbitmq-server-3a3b67e62ad22ddb7d0eedb2a93d1bcf247d26bf.tar.gz
ensure propagation of master death
Previously slaves were monitoring the master and sending a process_death message through gm in an attempt to get the updated gm state propagated (and thus members_changed callbacks getting invoked on slaves, which in turn trigger promotion). However, the DOWN notification for the master may well arrive and be processed, and the process_death message sent around the ring, before GM has noticed the master death, thus rendering the process_death broadcast ineffectual for its intended purpose. With the recent GM changes we can guarantee that at least one slave will be notified of the master death via GM. So we emit the process_death message then, and not on master DOWN (and ditch the master monitoring as a result). Since the new emission is triggered by a gm notification we know GM is aware of the master death, thus avoiding the aforementioned problem.
-rw-r--r--src/rabbit_mirror_queue_slave.erl16
1 files changed, 8 insertions, 8 deletions
diff --git a/src/rabbit_mirror_queue_slave.erl b/src/rabbit_mirror_queue_slave.erl
index 42680bfd..c18eff13 100644
--- a/src/rabbit_mirror_queue_slave.erl
+++ b/src/rabbit_mirror_queue_slave.erl
@@ -108,7 +108,6 @@ handle_go(Q = #amqqueue{name = QName}) ->
case rabbit_misc:execute_mnesia_transaction(
fun() -> init_it(Self, GM, Node, QName) end) of
{new, QPid, GMPids} ->
- erlang:monitor(process, QPid),
ok = file_handle_cache:register_callback(
rabbit_amqqueue, set_maximum_since_use, [Self]),
ok = rabbit_memory_monitor:register(
@@ -193,7 +192,8 @@ handle_call(go, _From, {not_started, Q} = NotStarted) ->
end;
handle_call({gm_deaths, LiveGMPids}, From,
- State = #state { q = Q = #amqqueue { name = QName, pid = MPid }}) ->
+ State = #state { gm = GM, q = Q = #amqqueue {
+ name = QName, pid = MPid }}) ->
Self = self(),
case rabbit_mirror_queue_misc:remove_from_queue(QName, Self, LiveGMPids) of
{error, not_found} ->
@@ -214,7 +214,12 @@ handle_call({gm_deaths, LiveGMPids}, From,
_ ->
%% master has changed to not us
gen_server2:reply(From, ok),
- erlang:monitor(process, Pid),
+ %% Since GM is by nature lazy we need to make sure
+ %% there is some traffic when a master dies, to
+ %% make sure all slaves get informed of the
+ %% death. That is all process_death does, create
+ %% some traffic.
+ ok = gm:broadcast(GM, process_death),
noreply(State #state { q = Q #amqqueue { pid = Pid } })
end
end;
@@ -294,11 +299,6 @@ handle_info(sync_timeout, State) ->
handle_info(timeout, State) ->
noreply(backing_queue_timeout(State));
-handle_info({'DOWN', _MonitorRef, process, MPid, _Reason},
- State = #state { gm = GM, q = #amqqueue { pid = MPid } }) ->
- ok = gm:broadcast(GM, process_death),
- noreply(State);
-
handle_info({'DOWN', _MonitorRef, process, ChPid, _Reason}, State) ->
local_sender_death(ChPid, State),
noreply(maybe_forget_sender(ChPid, down_from_ch, State));