Skip to content

Commit 2e10d21

Browse files
committed
rabbit_feature_flags: Take callback definition from correct node
[Why] The feature flag controller that is responsible for enabling a feature flag may be on a node that doesn't know this feature flag. This is supported by there is a bug when it queries the callback definition for that feature flag: it uses its own registry which does not have anything about this feature flag. This leads to a crash because the `run_callback/5` funtion tries to use the `undefined` atom returned by the registry as a map: crasher: initial call: rabbit_ff_controller:init/1 pid: <0.374.0> registered_name: rabbit_ff_controller exception error: bad map: undefined in function rabbit_ff_controller:run_callback/5 in call from rabbit_ff_controller:do_enable/3 (rabbit_ff_controller.erl, line 1244) in call from rabbit_ff_controller:update_feature_state_and_enable/2 (rabbit_ff_controller.erl, line 1180) in call from rabbit_ff_controller:enable_with_registry_locked/2 (rabbit_ff_controller.erl, line 1050) in call from rabbit_ff_controller:enable_many_locked/2 (rabbit_ff_controller.erl, line 991) in call from rabbit_ff_controller:enable_many/2 (rabbit_ff_controller.erl, line 979) in call from rabbit_ff_controller:updating_feature_flag_states/3 (rabbit_ff_controller.erl, line 307) in call from gen_statem:loop_state_callback/11 (gen_statem.erl, line 3735) [How] The callback definition is now queried from the first node in the list given as argument. For the common use case where all nodes know about a feature flag, the first node is the local one, so there should be no latency caused by the RPC. See #12963.
1 parent f413880 commit 2e10d21

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

deps/rabbit/src/rabbit_ff_controller.erl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1840,8 +1840,13 @@ enable_dependencies1(
18401840
rabbit_deprecated_features:is_feature_used_callback_ret() |
18411841
run_callback_error()}.
18421842

1843-
run_callback(Nodes, FeatureName, Command, Extra, Timeout) ->
1844-
FeatureProps = rabbit_ff_registry_wrapper:get(FeatureName),
1843+
run_callback([FirstNode | _] = Nodes, FeatureName, Command, Extra, Timeout) ->
1844+
%% We need to take the callback definition from a node in the `Nodes' list
1845+
%% because the local node may not know this feature flag and thus does not
1846+
%% have the callback definition.
1847+
FeatureProps = erpc:call(
1848+
FirstNode,
1849+
rabbit_ff_registry_wrapper, get, [FeatureName]),
18451850
Callbacks = maps:get(callbacks, FeatureProps, #{}),
18461851
case Callbacks of
18471852
#{Command := {CallbackMod, CallbackFun}}

0 commit comments

Comments
 (0)