106106 get_state /1 ,
107107 get_stability /1 ,
108108 get_require_level /1 ,
109+ get_experiment_level /1 ,
109110 check_node_compatibility /1 , check_node_compatibility /2 ,
110111 sync_feature_flags_with_cluster /2 ,
111112 refresh_feature_flags_after_app_load /0 ,
149150 doc_url => string (),
150151 stability => stability (),
151152 require_level => require_level (),
153+ experiment_level => experiment_level (),
152154 depends_on => [feature_name ()],
153155 callbacks =>
154156 #{callback_name () => callback_fun_name ()}}.
186188 doc_url => string (),
187189 stability => stability (),
188190 require_level => require_level (),
191+ experiment_level => experiment_level (),
189192 depends_on => [feature_name ()],
190193 callbacks =>
191194 #{callback_name () => callback_fun_name ()},
219222% % A soft required feature flag will be automatically enabled when a RabbitMQ
220223% % node is upgraded to a version where it is required.
221224
225+ -type experiment_level () :: unsupported | supported .
226+ % % The level of support of an experimental feature flag.
227+ % %
228+ % % At first, an experimental feature flag is offered to give a chance to users
229+ % % to try it and give feedback as part of the design and development of the
230+ % % feature. At this stage, it is unsupported: it must not be enabled in a
231+ % % production environment and upgrade to a later version of RabbitMQ while
232+ % % this experimental feature flag is enabled is not supported.
233+ % %
234+ % % Then, the experimental feature flag becomes supported. At this point, it is
235+ % % stable enough that upgrading is guarantied and help will be provided.
236+ % % However it is not mature enough to be marked as stable (which would make it
237+ % % enabled by default in a new deployment or when running `rabbitmqctl
238+ % % enable_feature_flag all'.
239+ % %
240+ % % The next step is to change its stability to `stable'. Once done, the
241+ % % `experiment_level()' field is irrelevant.
242+
222243-type callback_fun_name () :: {Module :: module (), Function :: atom ()}.
223244% % The name of the module and function to call when changing the state of
224245% % the feature flag.
@@ -809,6 +830,45 @@ get_require_level(FeatureProps) when ?IS_DEPRECATION(FeatureProps) ->
809830 _ -> none
810831 end .
811832
833+ - spec get_experiment_level
834+ (FeatureName ) -> ExperimentLevel | undefined when
835+ FeatureName :: feature_name (),
836+ ExperimentLevel :: experiment_level () | none ;
837+ (FeatureProps ) -> ExperimentLevel when
838+ FeatureProps ::
839+ feature_props_extended () |
840+ rabbit_deprecated_features :feature_props_extended (),
841+ ExperimentLevel :: experiment_level () | none .
842+ % % @doc
843+ % % Returns the experimental level of an experimental feature flag.
844+ % %
845+ % % The possible experiment levels are:
846+ % % <ul>
847+ % % <li>`unsupported': the experimental feature flag must not be enabled in
848+ % % production and upgrades with it enabled is unsupported.</li>
849+ % % <li>`supported': the experimental feature flag is not yet stable enough but
850+ % % upgrades are guarantied to be possible. This is returned too if the
851+ % % feature flag is stable or required.</li>
852+ % % </ul>
853+ % %
854+ % % @param FeatureName The name of the feature flag to check.
855+ % % @param FeatureProps A feature flag properties map.
856+ % % @returns `unsupported', `supported', or `undefined' if the given feature
857+ % % flag name doesn't correspond to a known feature flag.
858+
859+ get_experiment_level (FeatureName ) when is_atom (FeatureName ) ->
860+ case rabbit_ff_registry_wrapper :get (FeatureName ) of
861+ undefined -> undefined ;
862+ FeatureProps -> get_experiment_level (FeatureProps )
863+ end ;
864+ get_experiment_level (FeatureProps ) when ? IS_FEATURE_FLAG (FeatureProps ) ->
865+ case get_stability (FeatureProps ) of
866+ experimental -> maps :get (experiment_level , FeatureProps , unsupported );
867+ _ -> supported
868+ end ;
869+ get_experiment_level (FeatureProps ) when ? IS_DEPRECATION (FeatureProps ) ->
870+ supported .
871+
812872% % -------------------------------------------------------------------
813873% % Feature flags registry.
814874% % -------------------------------------------------------------------
@@ -968,6 +1028,7 @@ assert_feature_flag_is_valid(FeatureName, FeatureProps) ->
9681028 doc_url ,
9691029 stability ,
9701030 require_level ,
1031+ experiment_level ,
9711032 depends_on ,
9721033 callbacks ],
9731034 ? assertEqual ([], maps :keys (FeatureProps ) -- ValidProps ),
@@ -979,6 +1040,17 @@ assert_feature_flag_is_valid(FeatureName, FeatureProps) ->
9791040 ? assert (Stability =:= stable orelse
9801041 Stability =:= experimental orelse
9811042 Stability =:= required ),
1043+ ? assert (Stability =:= experimental orelse
1044+ not maps :is_key (experiment_level , FeatureProps )),
1045+ ? assert (Stability =:= required orelse
1046+ not maps :is_key (require_level , FeatureProps )),
1047+ RequireLevel = maps :get (require_level , FeatureProps , soft ),
1048+ ? assert (RequireLevel =:= hard orelse RequireLevel =:= soft ),
1049+ ExperimentLevel = maps :get (
1050+ experiment_level , FeatureProps ,
1051+ unsupported ),
1052+ ? assert (ExperimentLevel =:= unsupported orelse
1053+ ExperimentLevel =:= supported ),
9821054 ? assertNot (maps :is_key (migration_fun , FeatureProps )),
9831055 ? assertNot (maps :is_key (warning , FeatureProps )),
9841056 case FeatureProps of
0 commit comments