summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon MacMullen <simon@rabbitmq.com>2012-08-16 18:07:25 +0100
committerSimon MacMullen <simon@rabbitmq.com>2012-08-16 18:07:25 +0100
commit34df392854b305ce7934ac13c9000934c3abfb70 (patch)
treeb896434369de3ac86c7d4b70dc947b114723fdf6
parent416cf57c2487e934540f611c2e261e8494d9706f (diff)
downloadrabbitmq-server-34df392854b305ce7934ac13c9000934c3abfb70.tar.gz
Fix detection of mirror removal at clean shutdown
-rw-r--r--src/rabbit_mirror_queue_misc.erl31
1 files changed, 28 insertions, 3 deletions
diff --git a/src/rabbit_mirror_queue_misc.erl b/src/rabbit_mirror_queue_misc.erl
index 29e2d29f..51084874 100644
--- a/src/rabbit_mirror_queue_misc.erl
+++ b/src/rabbit_mirror_queue_misc.erl
@@ -20,6 +20,8 @@
drop_mirror/2, drop_mirror/3, add_mirror/2, add_mirror/3,
report_deaths/4, store_updated_slaves/1]).
+-export([is_really_alive0/1]). %% For RPC
+
-include("rabbit.hrl").
%%----------------------------------------------------------------------------
@@ -64,9 +66,8 @@ remove_from_queue(QueueName, DeadPids) ->
slave_pids = SPids }] ->
[QPid1 | SPids1] = Alive =
[Pid || Pid <- [QPid | SPids],
- not lists:member(node(Pid),
- DeadNodes) orelse
- rabbit_misc:is_process_alive(Pid)],
+ not lists:member(node(Pid), DeadNodes) orelse
+ is_really_alive(Pid)],
case {{QPid, SPids}, {QPid1, SPids1}} of
{Same, Same} ->
{ok, QPid1, []};
@@ -88,6 +89,30 @@ remove_from_queue(QueueName, DeadPids) ->
end
end).
+%% We want to find out if the pid is alive in case a node restarted
+%% quickly and we didn't notice until later (in which case we should
+%% do nothing). But if we are dealing with a queue going down because
+%% it's in a broker which is shutting down cleanly, its process could
+%% still be alive momentarily (since we heard about the death of the
+%% *GM* process) so ask the application controller whether rabbit is
+%% running - in the above case by the time the controller responds the
+%% process will have terminated.
+%%
+%% See bug 25104.
+
+is_really_alive(Pid) ->
+ %% Don't bother optimising the local case since we will only ever
+ %% call for a remote node
+ case rpc:call(node(Pid),
+ rabbit_mirror_queue_misc, is_process_alive0, [Pid]) of
+ true -> true;
+ _ -> false
+ end.
+
+is_really_alive0(Pid) ->
+ lists:keymember(rabbit, 1, application:which_applications())
+ andalso is_process_alive(Pid).
+
on_node_up() ->
Qs =
rabbit_misc:execute_mnesia_transaction(