From 0d8b75475a2f82aec86b4d9237d8a4d2dd6fc350 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Wed, 3 Nov 2021 01:40:05 +0300 Subject: Introduce a target cluster size hint setting This is meant to be used by deployment tools, core features and plugins that expect a certain minimum number of cluster nodes to be present. For example, certain setup steps in distributed plugins might require at least three nodes to be available. This is just a hint, not an enforced requirement. The default value is 1 so that for single node clusters, there would be no behavior changes. --- deps/rabbit/priv/schema/rabbit.schema | 12 ++++++++ deps/rabbit/src/rabbit_nodes.erl | 33 +++++++++++++++++----- .../test/config_schema_SUITE_data/rabbit.snippets | 9 ++++++ 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/deps/rabbit/priv/schema/rabbit.schema b/deps/rabbit/priv/schema/rabbit.schema index 29e9ce6a33..c850fa8a69 100644 --- a/deps/rabbit/priv/schema/rabbit.schema +++ b/deps/rabbit/priv/schema/rabbit.schema @@ -1124,6 +1124,18 @@ end}. {validators, ["non_zero_positive_integer"]} ]}. + +%% Target cluster size hint may be used by certain core features or plugins to perform +%% actions that should only be performed when a certain number of nodes (or a quorum of a certain number) +%% has already joined (started). +%% + +{mapping, "cluster_formation.target_cluster_size_hint", "rabbit.cluster_formation.target_cluster_size_hint", [ + {datatype, integer}, + {validators, ["non_zero_positive_integer"]} +]}. + + %% Classic config-driven peer discovery backend. %% %% Make clustering happen *automatically* at startup - only applied diff --git a/deps/rabbit/src/rabbit_nodes.erl b/deps/rabbit/src/rabbit_nodes.erl index eecf04f13e..092e8dc912 100644 --- a/deps/rabbit/src/rabbit_nodes.erl +++ b/deps/rabbit/src/rabbit_nodes.erl @@ -14,7 +14,7 @@ await_running_count/2, is_single_node_cluster/0, boot/0]). -export([persistent_cluster_id/0, seed_internal_cluster_id/0, seed_user_provided_cluster_name/0]). --export([all/0, all_running_with_hashes/0]). +-export([all/0, all_running_with_hashes/0, target_cluster_size_hint/0, reached_target_cluster_size/0]). -export([lock_id/1, lock_retries/0]). -include_lib("kernel/include/inet.hrl"). @@ -30,6 +30,8 @@ % 80 corresponds to a timeout of ca 300 seconds. -define(DEFAULT_LOCK_RETRIES, 80). +-define(DEFAULT_TARGET_CLUSTER_SIZE, 1). + %%---------------------------------------------------------------------------- %% API %%---------------------------------------------------------------------------- @@ -173,15 +175,32 @@ await_running_count_with_retries(TargetCount, Retries) -> all_running_with_hashes() -> maps:from_list([{erlang:phash2(Node), Node} || Node <- all_running()]). +-spec target_cluster_size_hint() -> non_neg_integer(). +target_cluster_size_hint() -> + cluster_formation_key_or_default(target_cluster_size_hint, ?DEFAULT_TARGET_CLUSTER_SIZE). + +-spec reached_target_cluster_size() -> boolean(). +reached_target_cluster_size() -> + running_count() >= target_cluster_size_hint(). + + -spec lock_id(Node :: node()) -> {ResourceId :: string(), LockRequesterId :: node()}. lock_id(Node) -> {cookie_hash(), Node}. -spec lock_retries() -> integer(). lock_retries() -> - case application:get_env(rabbit, cluster_formation) of - {ok, PropList} -> - proplists:get_value(internal_lock_retries, PropList, ?DEFAULT_LOCK_RETRIES); - undefined -> - ?DEFAULT_LOCK_RETRIES - end. + cluster_formation_key_or_default(internal_lock_retries, ?DEFAULT_LOCK_RETRIES). + + +%% +%% Implementation +%% + +cluster_formation_key_or_default(Key, Default) -> + case application:get_env(rabbit, cluster_formation) of + {ok, PropList} -> + proplists:get_value(Key, PropList, Default); + undefined -> + Default + end. \ No newline at end of file diff --git a/deps/rabbit/test/config_schema_SUITE_data/rabbit.snippets b/deps/rabbit/test/config_schema_SUITE_data/rabbit.snippets index 08ea31ff49..214a2d1e66 100644 --- a/deps/rabbit/test/config_schema_SUITE_data/rabbit.snippets +++ b/deps/rabbit/test/config_schema_SUITE_data/rabbit.snippets @@ -139,6 +139,15 @@ cluster_formation.dns.hostname = discovery.eng.example.local", []}, {cluster_formation_ram_ignored, "cluster_formation.node_type = ram",[],[]}, + {cluster_formation_target_cluster_size_hint, + "cluster_formation.target_cluster_size_hint = 3", + [{rabbit, [ + {cluster_formation, [ + {target_cluster_size_hint, 3} + ]} + ]}], + []}, + {tcp_listen_options, "tcp_listen_options.backlog = 128 tcp_listen_options.nodelay = true -- cgit v1.2.1