Skip to content

Commit 70d456b

Browse files
kjnilssondcorbacho
authored andcommitted
QQ: Avoid secondary process when repairing leader record.
* QQ: Avoid secondary process when repairing leader record. * dialyzer * Fix dialyzer complaint --------- Co-authored-by: Diana Parra Corbacho <[email protected]>
1 parent 795b0fa commit 70d456b

File tree

1 file changed

+32
-25
lines changed

1 file changed

+32
-25
lines changed

deps/rabbit/src/rabbit_quorum_queue.erl

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -193,18 +193,23 @@ start_cluster(Q) ->
193193
{error, {too_long, N}} ->
194194
rabbit_data_coercion:to_atom(ra:new_uid(N))
195195
end,
196-
{Leader, Followers} = rabbit_queue_location:select_leader_and_followers(Q, QuorumSize),
197-
LeaderId = {RaName, Leader},
196+
{LeaderNode, FollowerNodes} =
197+
rabbit_queue_location:select_leader_and_followers(Q, QuorumSize),
198+
LeaderId = {RaName, LeaderNode},
198199
NewQ0 = amqqueue:set_pid(Q, LeaderId),
199-
NewQ1 = amqqueue:set_type_state(NewQ0, #{nodes => [Leader | Followers]}),
200+
NewQ1 = amqqueue:set_type_state(NewQ0,
201+
#{nodes => [LeaderNode | FollowerNodes]}),
200202

201203
rabbit_log:debug("Will start up to ~w replicas for quorum ~ts with leader on node '~ts'",
202-
[QuorumSize, rabbit_misc:rs(QName), Leader]),
204+
[QuorumSize, rabbit_misc:rs(QName), LeaderNode]),
203205
case rabbit_amqqueue:internal_declare(NewQ1, false) of
204206
{created, NewQ} ->
205207
RaConfs = [make_ra_conf(NewQ, ServerId)
206208
|| ServerId <- members(NewQ)],
207-
try erpc_call(Leader, ra, start_cluster,
209+
210+
%% khepri projections on remote nodes are eventually consistent
211+
wait_for_projections(LeaderNode, QName),
212+
try erpc_call(LeaderNode, ra, start_cluster,
208213
[?RA_SYSTEM, RaConfs, ?START_CLUSTER_TIMEOUT],
209214
?START_CLUSTER_RPC_TIMEOUT) of
210215
{ok, _, _} ->
@@ -228,10 +233,10 @@ start_cluster(Q) ->
228233
ActingUser}]),
229234
{new, NewQ};
230235
{error, Error} ->
231-
declare_queue_error(Error, NewQ, Leader, ActingUser)
236+
declare_queue_error(Error, NewQ, LeaderNode, ActingUser)
232237
catch
233238
error:Error ->
234-
declare_queue_error(Error, NewQ, Leader, ActingUser)
239+
declare_queue_error(Error, NewQ, LeaderNode, ActingUser)
235240
end;
236241
{existing, _} = Ex ->
237242
Ex
@@ -321,26 +326,28 @@ local_or_remote_handler(ChPid, Module, Function, Args) ->
321326
end.
322327

323328
become_leader(QName, Name) ->
329+
%% as this function is called synchronously when a ra node becomes leader
330+
%% we need to ensure there is no chance of blocking as else the ra node
331+
%% may not be able to establish its leadership
332+
spawn(fun () -> become_leader0(QName, Name) end).
333+
334+
become_leader0(QName, Name) ->
324335
Fun = fun (Q1) ->
325336
amqqueue:set_state(
326337
amqqueue:set_pid(Q1, {Name, node()}),
327338
live)
328339
end,
329-
%% as this function is called synchronously when a ra node becomes leader
330-
%% we need to ensure there is no chance of blocking as else the ra node
331-
%% may not be able to establish its leadership
332-
spawn(fun() ->
333-
_ = rabbit_amqqueue:update(QName, Fun),
334-
case rabbit_amqqueue:lookup(QName) of
335-
{ok, Q0} when ?is_amqqueue(Q0) ->
336-
Nodes = get_nodes(Q0),
337-
[_ = erpc_call(Node, ?MODULE, rpc_delete_metrics,
338-
[QName], ?RPC_TIMEOUT)
339-
|| Node <- Nodes, Node =/= node()];
340-
_ ->
341-
ok
342-
end
343-
end).
340+
_ = rabbit_amqqueue:update(QName, Fun),
341+
case rabbit_amqqueue:lookup(QName) of
342+
{ok, Q0} when ?is_amqqueue(Q0) ->
343+
Nodes = get_nodes(Q0),
344+
_ = [_ = erpc_call(Node, ?MODULE, rpc_delete_metrics,
345+
[QName], ?RPC_TIMEOUT)
346+
|| Node <- Nodes, Node =/= node()],
347+
ok;
348+
_ ->
349+
ok
350+
end.
344351

345352
-spec all_replica_states() -> {node(), #{atom() => atom()}}.
346353
all_replica_states() ->
@@ -496,7 +503,7 @@ handle_tick(QName,
496503
catch
497504
_:Err ->
498505
rabbit_log:debug("~ts: handle tick failed with ~p",
499-
[rabbit_misc:rs(QName), Err]),
506+
[rabbit_misc:rs(QName), Err]),
500507
ok
501508
end
502509
end).
@@ -512,7 +519,7 @@ repair_leader_record(QName, Self) ->
512519
rabbit_log:debug("~ts: repairing leader record",
513520
[rabbit_misc:rs(QName)]),
514521
{_, Name} = erlang:process_info(Self, registered_name),
515-
become_leader(QName, Name),
522+
ok = become_leader0(QName, Name),
516523
ok
517524
end,
518525
ok.
@@ -579,7 +586,7 @@ recover(_Vhost, Queues) ->
579586
Err1 == name_not_registered ->
580587
rabbit_log:warning("Quorum queue recovery: configured member of ~ts was not found on this node. Starting member as a new one. "
581588
"Context: ~s",
582-
[rabbit_misc:rs(QName), Err1]),
589+
[rabbit_misc:rs(QName), Err1]),
583590
% queue was never started on this node
584591
% so needs to be started from scratch.
585592
case start_server(make_ra_conf(Q0, ServerId)) of

0 commit comments

Comments
 (0)