Skip to content

Commit 10013f5

Browse files
committed
Make master locator min-masters count queues and not bindings.
The min-masters locator was originally designed to count bindings, but this was confusing for people wanting to distribute queues rather than routes to queues. This was changed in 1d413ea to count only queues which have at least one binding. But queues always have bindings (default) and hence it's equivalent to listing queues. Since default bindings are removed the location was broken. This commit changes the location to actually list queues rather than bindings.
1 parent 76acfa4 commit 10013f5

File tree

1 file changed

+29
-41
lines changed

1 file changed

+29
-41
lines changed

src/rabbit_queue_location_min_masters.erl

Lines changed: 29 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -38,45 +38,33 @@ description() ->
3838
<<"Locate queue master node from cluster node with least bound queues">>}].
3939

4040
queue_master_location(#amqqueue{} = Q) ->
41-
Cluster = rabbit_queue_master_location_misc:all_nodes(Q),
42-
VHosts = rabbit_vhost:list(),
43-
BoundQueueMasters = get_bound_queue_masters_per_vhost(VHosts, []),
44-
{_Count, MinMaster}= get_min_master(Cluster, BoundQueueMasters),
45-
{ok, MinMaster}.
41+
Cluster = rabbit_queue_master_location_misc:all_nodes(Q),
42+
QueueNames = rabbit_amqqueue:list_names(),
43+
MastersPerNode = lists:foldl(
44+
fun(#resource{virtual_host = VHost, name = QueueName}, NodeMasters) ->
45+
case rabbit_queue_master_location_misc:lookup_master(QueueName, VHost) of
46+
{ok, Master} when is_atom(Master) ->
47+
case maps:is_key(Master, NodeMasters) of
48+
true -> maps:update_with(Master,
49+
fun(N) -> N + 1 end,
50+
NodeMasters);
51+
false -> NodeMasters
52+
end;
53+
_ -> NodeMasters
54+
end
55+
end,
56+
maps:from_list([{N, 0} || N <- Cluster]),
57+
QueueNames),
4658

47-
%%---------------------------------------------------------------------------
48-
%% Private helper functions
49-
%%---------------------------------------------------------------------------
50-
get_min_master(Cluster, BoundQueueMasters) ->
51-
lists:min([ {count_masters(Node, BoundQueueMasters), Node} ||
52-
Node <- Cluster ]).
53-
54-
count_masters(Node, Masters) ->
55-
length([ X || X <- Masters, X == Node ]).
56-
57-
get_bound_queue_masters_per_vhost([], Acc) ->
58-
lists:flatten(Acc);
59-
get_bound_queue_masters_per_vhost([VHost|RemVHosts], Acc) ->
60-
BoundQueueNames =
61-
lists:filtermap(
62-
fun(#binding{destination =#resource{kind = queue,
63-
name = QueueName}}) ->
64-
{true, QueueName};
65-
(_) ->
66-
false
67-
end,
68-
rabbit_binding:list(VHost)),
69-
UniqQueueNames = lists:usort(BoundQueueNames),
70-
BoundQueueMasters = get_queue_masters(VHost, UniqQueueNames, []),
71-
get_bound_queue_masters_per_vhost(RemVHosts, [BoundQueueMasters|Acc]).
72-
73-
74-
get_queue_masters(_VHost, [], BoundQueueNodes) -> BoundQueueNodes;
75-
get_queue_masters(VHost, [QueueName | RemQueueNames], QueueMastersAcc) ->
76-
QueueMastersAcc0 = case rabbit_queue_master_location_misc:lookup_master(
77-
QueueName, VHost) of
78-
{ok, Master} when is_atom(Master) ->
79-
[Master|QueueMastersAcc];
80-
_ -> QueueMastersAcc
81-
end,
82-
get_queue_masters(VHost, RemQueueNames, QueueMastersAcc0).
59+
{MinNode, _NMasters} = maps:fold(
60+
fun(Node, NMasters, init) ->
61+
{Node, NMasters};
62+
(Node, NMasters, {MinNode, MinMasters}) ->
63+
case NMasters < MinMasters of
64+
true -> {Node, NMasters};
65+
false -> {MinNode, MinMasters}
66+
end
67+
end,
68+
init,
69+
MastersPerNode),
70+
{ok, MinNode}.

0 commit comments

Comments
 (0)