summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon MacMullen <simon@rabbitmq.com>2015-01-30 12:27:20 +0000
committerSimon MacMullen <simon@rabbitmq.com>2015-01-30 12:27:20 +0000
commit5d8f492f902e2fcc00e3dd624ce5f895ca1f7b90 (patch)
tree4969270845a5dea60a0403d40754172502b2fe50
parent9388c6613c1789516614077868b1b7417979ddff (diff)
downloadrabbitmq-server-git-5d8f492f902e2fcc00e3dd624ce5f895ca1f7b90.tar.gz
Correctly determine whether offline promotion is likely to work.
-rw-r--r--src/rabbit_amqqueue.erl30
1 files changed, 20 insertions, 10 deletions
diff --git a/src/rabbit_amqqueue.erl b/src/rabbit_amqqueue.erl
index 8d5971542f..15e639f27e 100644
--- a/src/rabbit_amqqueue.erl
+++ b/src/rabbit_amqqueue.erl
@@ -739,18 +739,28 @@ forget_node_for_queue(DeadNode, [DeadNode | T], Q) ->
forget_node_for_queue(DeadNode, T, Q);
forget_node_for_queue(DeadNode, [H|T], Q) ->
- case H =/= node() andalso %% TODO not really good enough test
- lists:member(H, rabbit_mnesia:cluster_nodes(running)) of
- true ->
- forget_node_for_queue(DeadNode, T, Q);
- false ->
- %% Promote a slave while down - it should recover as a
- %% master. We try to take the oldest slave here for best
- %% chance of recovery.
- Q1 = Q#amqqueue{pid = rabbit_misc:node_to_fake_pid(H)},
- ok = mnesia:write(rabbit_durable_queue, Q1, write)
+ case node_permits_offline_promotion(H) of
+ false -> forget_node_for_queue(DeadNode, T, Q);
+ true -> Q1 = Q#amqqueue{pid = rabbit_misc:node_to_fake_pid(H)},
+ %% Promote a slave while down - it should recover as a
+ %% master. We try to take the oldest slave here for best
+ %% chance of recovery.
+ ok = mnesia:write(rabbit_durable_queue, Q1, write)
end.
+node_permits_offline_promotion(Node) ->
+ case node() of
+ Node -> not rabbit:is_running(); %% [1]
+ _ -> Running = rabbit_mnesia:cluster_nodes(running),
+ not lists:member(Node, Running) %% [2]
+ end.
+%% [1] In this case if we are a real running node (i.e. rabbitmqctl
+%% has RPCed into us) then we cannot allow promotion. If on the other
+%% hand we *are* rabbitmqctl impersonating the node for offline
+%% node-forgetting then we can.
+%%
+%% [2] This is simpler; as long as it's down that's OK
+
run_backing_queue(QPid, Mod, Fun) ->
gen_server2:cast(QPid, {run_backing_queue, Mod, Fun}).