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