Skip to content

Commit d4020f5

Browse files
committed
Merge branch 'Ayanda-D-rabbitmq-server-914' into stable
2 parents c633856 + 6fc561f commit d4020f5

File tree

5 files changed

+74
-8
lines changed

5 files changed

+74
-8
lines changed

src/gm.erl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,9 @@ handle_info({'DOWN', MRef, process, _Pid, Reason},
760760
end;
761761
handle_info(_, State) ->
762762
%% Discard any unexpected messages, such as late replies from neighbour_call/2
763+
%% TODO: For #gm_group{} related info messages, it could be worthwhile to
764+
%% change_view/2, as this might reflect an alteration in the gm group, meaning
765+
%% we now need to update our state. see rabbitmq-server#914.
763766
noreply(State).
764767

765768
terminate(Reason, #state { module = Module, callback_args = Args }) ->
@@ -1596,7 +1599,9 @@ check_membership(Self, #gm_group{members = M} = Group) ->
15961599
Group;
15971600
false ->
15981601
throw(lost_membership)
1599-
end.
1602+
end;
1603+
check_membership(_Self, {error, not_found}) ->
1604+
throw(lost_membership).
16001605

16011606
check_membership(GroupName) ->
16021607
case dirty_read_group(GroupName) of

src/rabbit_mirror_queue_coordinator.erl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,15 @@ handle_cast({gm_deaths, DeadGMPids},
355355
DeadPids),
356356
rabbit_mirror_queue_misc:add_mirrors(QueueName, ExtraNodes, async),
357357
noreply(State);
358+
{ok, _MPid0, DeadPids, _ExtraNodes} ->
359+
%% see rabbitmq-server#914;
360+
%% Different slave is now master, stop current coordinator normally.
361+
%% Initiating queue is now slave and the least we could do is report
362+
%% deaths which we 'think' we saw.
363+
%% NOTE: Reported deaths here, could be inconsistant.
364+
rabbit_mirror_queue_misc:report_deaths(MPid, false, QueueName,
365+
DeadPids),
366+
{stop, normal, State};
358367
{error, not_found} ->
359368
{stop, normal, State}
360369
end;

src/rabbit_mirror_queue_misc.erl

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ remove_from_queue(QueueName, Self, DeadGMPids) ->
7676
rabbit_misc:execute_mnesia_transaction(
7777
fun () ->
7878
%% Someone else could have deleted the queue before we
79-
%% get here.
79+
%% get here. Or, gm group could've altered. see rabbitmq-server#914
8080
case mnesia:read({rabbit_queue, QueueName}) of
8181
[] -> {error, not_found};
8282
[Q = #amqqueue { pid = QPid,
@@ -90,15 +90,25 @@ remove_from_queue(QueueName, Self, DeadGMPids) ->
9090
AlivePids = [Pid || {_GM, Pid} <- AliveGM],
9191
Alive = [Pid || Pid <- [QPid | SPids],
9292
lists:member(Pid, AlivePids)],
93-
{QPid1, SPids1} = promote_slave(Alive),
93+
{QPid1, SPids1} = case Alive of
94+
[] ->
95+
%% GM altered, & if all pids are
96+
%% perceived as dead, rather do
97+
%% do nothing here, & trust the
98+
%% promoted slave to have updated
99+
%% mnesia during the alteration.
100+
{QPid, SPids};
101+
_ -> promote_slave(Alive)
102+
end,
94103
Extra =
95104
case {{QPid, SPids}, {QPid1, SPids1}} of
96105
{Same, Same} ->
97106
[];
98107
_ when QPid =:= QPid1 orelse QPid1 =:= Self ->
99108
%% Either master hasn't changed, so
100109
%% we're ok to update mnesia; or we have
101-
%% become the master.
110+
%% become the master. If gm altered,
111+
%% we have no choice but to proceed.
102112
Q1 = Q#amqqueue{pid = QPid1,
103113
slave_pids = SPids1,
104114
gm_pids = AliveGM},

src/rabbit_mirror_queue_slave.erl

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,9 +225,15 @@ handle_call({gm_deaths, DeadGMPids}, From,
225225
_ ->
226226
%% master has changed to not us
227227
gen_server2:reply(From, ok),
228-
%% assertion, we don't need to add_mirrors/2 in this
229-
%% branch, see last clause in remove_from_queue/2
230-
[] = ExtraNodes,
228+
%% see rabbitmq-server#914;
229+
%% It's not always guaranteed that we won't have ExtraNodes.
230+
%% If gm alters, master can change to not us with extra nodes,
231+
%% in which case we attempt to add mirrors on those nodes.
232+
case ExtraNodes of
233+
[] -> void;
234+
_ -> rabbit_mirror_queue_misc:add_mirrors(
235+
QName, ExtraNodes, async)
236+
end,
231237
%% Since GM is by nature lazy we need to make sure
232238
%% there is some traffic when a master dies, to
233239
%% make sure all slaves get informed of the

test/gm_SUITE.erl

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ all() ->
3939
confirmed_broadcast,
4040
member_death,
4141
receive_in_order,
42-
unexpected_msg
42+
unexpected_msg,
43+
down_in_members_change
4344
].
4445

4546
init_per_suite(Config) ->
@@ -123,6 +124,41 @@ unexpected_msg(_Config) ->
123124
passed
124125
end).
125126

127+
down_in_members_change(_Config) ->
128+
%% Setup
129+
ok = gm:create_tables(),
130+
{ok, Pid} = gm:start_link(?MODULE, ?MODULE, self(),
131+
fun rabbit_misc:execute_mnesia_transaction/1),
132+
passed = receive_joined(Pid, [Pid], timeout_joining_gm_group_1),
133+
{ok, Pid2} = gm:start_link(?MODULE, ?MODULE, self(),
134+
fun rabbit_misc:execute_mnesia_transaction/1),
135+
passed = receive_joined(Pid2, [Pid, Pid2], timeout_joining_gm_group_2),
136+
passed = receive_birth(Pid, Pid2, timeout_waiting_for_birth_2),
137+
138+
%% Test. Simulate that the gm group is deleted (forget_group) while
139+
%% processing the 'DOWN' message from the neighbour
140+
process_flag(trap_exit, true),
141+
ok = meck:new(mnesia, [passthrough]),
142+
ok = meck:expect(mnesia, read, fun({gm_group, ?MODULE}) ->
143+
[];
144+
(Key) ->
145+
meck:passthrough([Key])
146+
end),
147+
gm:leave(Pid2),
148+
Passed = receive
149+
{'EXIT', Pid, normal} ->
150+
passed;
151+
{'EXIT', Pid, _} ->
152+
crashed
153+
after 15000 ->
154+
timeout
155+
end,
156+
%% Cleanup
157+
meck:unload(mnesia),
158+
process_flag(trap_exit, false),
159+
passed = Passed.
160+
161+
126162
do_broadcast(Fun) ->
127163
with_two_members(broadcast_fun(Fun)).
128164

0 commit comments

Comments
 (0)