1%% This Source Code Form is subject to the terms of the Mozilla Public 2%% License, v. 2.0. If a copy of the MPL was not distributed with this 3%% file, You can obtain one at https://mozilla.org/MPL/2.0/. 4%% 5%% Copyright (c) 2010-2021 VMware, Inc. or its affiliates. All rights reserved. 6%% 7 8-module(rabbit_mirror_queue_mode_exactly). 9 10-include_lib("rabbit_common/include/rabbit.hrl"). 11 12-behaviour(rabbit_mirror_queue_mode). 13 14-export([description/0, suggested_queue_nodes/5, validate_policy/1]). 15 16-rabbit_boot_step({?MODULE, 17 [{description, "mirror mode exactly"}, 18 {mfa, {rabbit_registry, register, 19 [ha_mode, <<"exactly">>, ?MODULE]}}, 20 {requires, rabbit_registry}, 21 {enables, kernel_ready}]}). 22 23description() -> 24 [{description, <<"Mirror queue to a specified number of nodes">>}]. 25 26%% When we need to add nodes, we randomise our candidate list as a 27%% crude form of load-balancing. TODO it would also be nice to 28%% randomise the list of ones to remove when we have too many - we 29%% would have to take account of synchronisation though. 30suggested_queue_nodes(Count, MNode, SNodes, _SSNodes, Poss) -> 31 SCount = Count - 1, 32 {MNode, case SCount > length(SNodes) of 33 true -> Cand = shuffle((Poss -- [MNode]) -- SNodes), 34 SNodes ++ lists:sublist(Cand, SCount - length(SNodes)); 35 false -> lists:sublist(SNodes, SCount) 36 end}. 37 38shuffle(L) -> 39 {_, L1} = lists:unzip(lists:keysort(1, [{rand:uniform(), N} || N <- L])), 40 L1. 41 42validate_policy(N) when is_integer(N) andalso N > 0 -> 43 ok; 44validate_policy(Params) -> 45 {error, "ha-mode=\"exactly\" takes an integer, ~p given", [Params]}. 46