diff options
author | Simon MacMullen <simon@rabbitmq.com> | 2012-08-16 18:07:25 +0100 |
---|---|---|
committer | Simon MacMullen <simon@rabbitmq.com> | 2012-08-16 18:07:25 +0100 |
commit | 34df392854b305ce7934ac13c9000934c3abfb70 (patch) | |
tree | b896434369de3ac86c7d4b70dc947b114723fdf6 | |
parent | 416cf57c2487e934540f611c2e261e8494d9706f (diff) | |
download | rabbitmq-server-34df392854b305ce7934ac13c9000934c3abfb70.tar.gz |
Fix detection of mirror removal at clean shutdown
-rw-r--r-- | src/rabbit_mirror_queue_misc.erl | 31 |
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( |