@@ -278,9 +278,14 @@ start_cluster(Q) ->
278
278
UIDs = maps :from_list ([{Node , ra :new_uid (ra_lib :to_binary (RaName ))}
279
279
|| Node <- [LeaderNode | FollowerNodes ]]),
280
280
NewQ0 = amqqueue :set_pid (Q , LeaderId ),
281
- NewQ1 = amqqueue :set_type_state (NewQ0 ,
282
- #{nodes => [LeaderNode | FollowerNodes ],
283
- uids => UIDs }),
281
+ NewQ1 = case rabbit_feature_flags :is_enabled (track_qq_members_uids ) of
282
+ false ->
283
+ amqqueue :set_type_state (NewQ0 ,
284
+ #{nodes => [LeaderNode | FollowerNodes ]});
285
+ true ->
286
+ amqqueue :set_type_state (NewQ0 ,
287
+ #{nodes => UIDs })
288
+ end ,
284
289
285
290
Versions = [V || {ok , V } <- erpc :multicall (FollowerNodes ,
286
291
rabbit_fifo , version , [],
@@ -725,7 +730,7 @@ repair_amqqueue_nodes(Q0) ->
725
730
{Name , _ } = amqqueue :get_pid (Q0 ),
726
731
Members = ra_leaderboard :lookup_members (Name ),
727
732
RaNodes = [N || {_ , N } <- Members ],
728
- #{ nodes : = Nodes } = amqqueue : get_type_state (Q0 ),
733
+ Nodes = get_nodes (Q0 ),
729
734
case lists :sort (RaNodes ) =:= lists :sort (Nodes ) of
730
735
true ->
731
736
% % up to date
@@ -734,7 +739,18 @@ repair_amqqueue_nodes(Q0) ->
734
739
% % update amqqueue record
735
740
Fun = fun (Q ) ->
736
741
TS0 = amqqueue :get_type_state (Q ),
737
- TS = TS0 #{nodes => RaNodes },
742
+ TS = case rabbit_feature_flags :is_enabled (track_qq_members_uids )
743
+ andalso has_uuid_tracking (TS0 )
744
+ of
745
+ false ->
746
+ TS0 #{nodes => RaNodes };
747
+ true ->
748
+ RaUids = maps :from_list ([{N , erpc :call (N , ra_directory , uid_of ,
749
+ [? RA_SYSTEM , Name ],
750
+ ? RPC_TIMEOUT )}
751
+ || N <- RaNodes ]),
752
+ TS0 #{nodes => RaUids }
753
+ end ,
738
754
amqqueue :set_type_state (Q , TS )
739
755
end ,
740
756
_ = rabbit_amqqueue :update (QName , Fun ),
@@ -795,10 +811,9 @@ recover(_Vhost, Queues) ->
795
811
QName = amqqueue :get_name (Q0 ),
796
812
MutConf = make_mutable_config (Q0 ),
797
813
RaUId = ra_directory :uid_of (? RA_SYSTEM , Name ),
798
- QTypeState0 = amqqueue :get_type_state (Q0 ),
799
- RaUIds = maps :get (uids , QTypeState0 , undefined ),
800
- QTypeState = case RaUIds of
801
- undefined ->
814
+ #{nodes := Nodes } = QTypeState0 = amqqueue :get_type_state (Q0 ),
815
+ QTypeState = case Nodes of
816
+ List when is_list (List ) ->
802
817
% % Queue is not aware of node to uid mapping, do nothing
803
818
QTypeState0 ;
804
819
#{node () := RaUId } ->
@@ -809,7 +824,7 @@ recover(_Vhost, Queues) ->
809
824
% % does not match the one returned by ra_directory, regen uid
810
825
maybe_delete_data_dir (RaUId ),
811
826
NewRaUId = ra :new_uid (ra_lib :to_binary (Name )),
812
- QTypeState0 #{uids := RaUIds #{node () => NewRaUId }}
827
+ QTypeState0 #{nodes := Nodes #{node () => NewRaUId }}
813
828
end ,
814
829
Q = amqqueue :set_type_state (Q0 , QTypeState ),
815
830
Res = case ra :restart_server (? RA_SYSTEM , ServerId , MutConf ) of
@@ -1412,21 +1427,20 @@ do_add_member(Q0, Node, Membership, Timeout)
1412
1427
% % TODO parallel calls might crash this, or add a duplicate in quorum_nodes
1413
1428
ServerId = {RaName , Node },
1414
1429
Members = members (Q0 ),
1415
- QTypeState0 = amqqueue :get_type_state (Q0 ),
1416
- RaUIds = maps :get (uids , QTypeState0 , undefined ),
1417
- QTypeState = case RaUIds of
1418
- undefined ->
1419
- % % Queue is not aware of node to uid mapping, do nothing
1420
- QTypeState0 ;
1421
- #{Node := _ } ->
1422
- % % Queue is aware and uid for targeted node exists, do nothing
1423
- QTypeState0 ;
1424
- _ ->
1425
- % % Queue is aware but current node has no UId, regen uid
1426
- NewRaUId = ra :new_uid (ra_lib :to_binary (RaName )),
1427
- QTypeState0 #{uids := RaUIds #{Node => NewRaUId }}
1428
- end ,
1429
- Q = amqqueue :set_type_state (Q0 , QTypeState ),
1430
+ QTypeState0 = #{nodes := _Nodes }= amqqueue :get_type_state (Q0 ),
1431
+ NewRaUId = ra :new_uid (ra_lib :to_binary (RaName )),
1432
+ % QTypeState = case Nodes of
1433
+ % L when is_list(L) ->
1434
+ % %% Queue is not aware of node to uid mapping, just add the new node
1435
+ % QTypeState0#{nodes := lists:usort([Node | Nodes])};
1436
+ % #{Node := _} ->
1437
+ % %% Queue is aware and uid for targeted node exists, do nothing
1438
+ % QTypeState0;
1439
+ % _ ->
1440
+ % %% Queue is aware but current node has no UId, regen uid
1441
+ % QTypeState0#{nodes := Nodes#{Node => NewRaUId}}
1442
+ % end,
1443
+ Q = amqqueue :set_type_state (Q0 , QTypeState0 ),
1430
1444
MachineVersion = erpc_call (Node , rabbit_fifo , version , [], infinity ),
1431
1445
Conf = make_ra_conf (Q , ServerId , Membership , MachineVersion ),
1432
1446
case ra :start_server (? RA_SYSTEM , Conf ) of
@@ -1442,8 +1456,12 @@ do_add_member(Q0, Node, Membership, Timeout)
1442
1456
{ok , {RaIndex , RaTerm }, Leader } ->
1443
1457
Fun = fun (Q1 ) ->
1444
1458
Q2 = update_type_state (
1445
- Q1 , fun (#{nodes := Nodes } = Ts ) ->
1446
- Ts #{nodes => lists :usort ([Node | Nodes ])}
1459
+ Q1 , fun (#{nodes := NodesList } = Ts ) when is_list (NodesList ) ->
1460
+ Ts #{nodes => lists :usort ([Node | NodesList ])};
1461
+ (#{nodes := #{Node := _ } = _NodesMap } = Ts ) ->
1462
+ Ts ;
1463
+ (#{nodes := NodesMap } = Ts ) when is_map (NodesMap ) ->
1464
+ Ts #{nodes => maps :put (Node , NewRaUId , NodesMap )}
1447
1465
end ),
1448
1466
amqqueue :set_pid (Q2 , Leader )
1449
1467
end ,
@@ -1516,12 +1534,10 @@ delete_member(Q, Node) when ?amqqueue_is_quorum(Q) ->
1516
1534
Fun = fun (Q1 ) ->
1517
1535
update_type_state (
1518
1536
Q1 ,
1519
- fun (#{nodes := Nodes ,
1520
- uids := UIds } = Ts ) ->
1521
- Ts #{nodes => lists :delete (Node , Nodes ),
1522
- uids => maps :remove (Node , UIds )};
1523
- (#{nodes := Nodes } = Ts ) ->
1524
- Ts #{nodes => lists :delete (Node , Nodes )}
1537
+ fun (#{nodes := Nodes } = Ts ) when is_list (Nodes ) ->
1538
+ Ts #{nodes => lists :delete (Node , Nodes )};
1539
+ (#{nodes := Nodes } = Ts ) when is_map (Nodes ) ->
1540
+ Ts #{nodes => maps :remove (Node , Nodes )}
1525
1541
end )
1526
1542
end ,
1527
1543
_ = rabbit_amqqueue :update (QName , Fun ),
@@ -2067,7 +2083,12 @@ make_mutable_config(Q) ->
2067
2083
2068
2084
get_nodes (Q ) when ? is_amqqueue (Q ) ->
2069
2085
#{nodes := Nodes } = amqqueue :get_type_state (Q ),
2070
- Nodes .
2086
+ case Nodes of
2087
+ List when is_list (List ) ->
2088
+ List ;
2089
+ Map when is_map (Map ) ->
2090
+ maps :keys (Map )
2091
+ end .
2071
2092
2072
2093
get_connected_nodes (Q ) when ? is_amqqueue (Q ) ->
2073
2094
ErlangNodes = [node () | nodes ()],
@@ -2423,3 +2444,8 @@ queue_vm_stats_sups() ->
2423
2444
queue_vm_ets () ->
2424
2445
{[quorum_ets ],
2425
2446
[[ra_log_ets ]]}.
2447
+
2448
+ has_uuid_tracking (#{nodes := Nodes }) when is_map (Nodes ) ->
2449
+ true ;
2450
+ has_uuid_tracking (_QTypeState ) ->
2451
+ false .
0 commit comments