Skip to content

Commit 8a67ebf

Browse files
Merge pull request #8127 from rabbitmq/mergify/bp/v3.12.x/pr-8112
2 parents 49365b8 + cebbf02 commit 8a67ebf

File tree

2 files changed

+53
-5
lines changed

2 files changed

+53
-5
lines changed

deps/rabbit/src/rabbit_ff_registry_factory.erl

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
release_state_change_lock/0]).
2020

2121
-ifdef(TEST).
22-
-export([registry_loading_lock/0]).
22+
-export([registry_loading_lock/0,
23+
purge_old_registry/1]).
2324
-endif.
2425

2526
-define(FF_STATE_CHANGE_LOCK, {feature_flags_state_change, self()}).
@@ -734,9 +735,14 @@ registry_vsn() ->
734735
proplists:get_value(vsn, Attrs, undefined).
735736

736737
purge_old_registry(Mod) ->
737-
case code:is_loaded(Mod) of
738-
{file, _} -> do_purge_old_registry(Mod);
739-
false -> ok
738+
case erlang:check_process_code(self(), rabbit_ff_registry) of
739+
false ->
740+
case code:is_loaded(Mod) of
741+
{file, _} -> do_purge_old_registry(Mod);
742+
false -> ok
743+
end;
744+
true ->
745+
ok
740746
end.
741747

742748
do_purge_old_registry(Mod) ->

deps/rabbit/test/feature_flags_SUITE.erl

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
registry_general_usage/1,
2727
registry_concurrent_reloads/1,
28+
try_to_deadlock_in_registry_reload/1,
2829
enable_feature_flag_in_a_healthy_situation/1,
2930
enable_unsupported_feature_flag_in_a_healthy_situation/1,
3031
enable_feature_flag_when_ff_file_is_unwritable/1,
@@ -100,7 +101,8 @@ groups() ->
100101
{registry, [],
101102
[
102103
registry_general_usage,
103-
registry_concurrent_reloads
104+
registry_concurrent_reloads,
105+
try_to_deadlock_in_registry_reload
104106
]},
105107
{feature_flags_v2, [], Groups}
106108
].
@@ -557,6 +559,46 @@ registry_spammer1(FeatureNames) ->
557559
?assertEqual(FeatureNames, ?list_ff(all)),
558560
registry_spammer1(FeatureNames).
559561

562+
try_to_deadlock_in_registry_reload(_Config) ->
563+
rabbit_ff_registry_factory:purge_old_registry(rabbit_ff_registry),
564+
_ = code:delete(rabbit_ff_registry),
565+
?assertEqual(false, code:is_loaded(rabbit_ff_registry)),
566+
567+
FeatureName = ?FUNCTION_NAME,
568+
FeatureProps = #{provided_by => rabbit,
569+
stability => stable},
570+
571+
Lock = rabbit_ff_registry_factory:registry_loading_lock(),
572+
global:set_lock(Lock, [node()]),
573+
574+
Parent = self(),
575+
ProcessA = spawn_link(
576+
fun() ->
577+
FF = rabbit_ff_registry:get(FeatureName),
578+
erlang:unlink(Parent),
579+
Parent ! {self(), FF}
580+
end),
581+
timer:sleep(1000),
582+
583+
ct:pal("Inject arbitrary feature flag to reload registry"),
584+
rabbit_feature_flags:inject_test_feature_flags(
585+
#{FeatureName => FeatureProps}),
586+
587+
ct:pal("Release registry loading lock"),
588+
global:del_lock(Lock, [node()]),
589+
590+
ct:pal("Waiting for process A to exit"),
591+
receive
592+
{ProcessA, FF} ->
593+
?assertEqual(FeatureProps, FF),
594+
ok
595+
after 10000 ->
596+
{_, Stacktrace} = erlang:process_info(
597+
ProcessA, current_stacktrace),
598+
ct:pal("Process A stuck; stacktrace: ~p", [Stacktrace]),
599+
error(registry_reload_deadlock)
600+
end.
601+
560602
enable_feature_flag_in_a_healthy_situation(Config) ->
561603
FeatureName = ff_from_testsuite,
562604
ClusterSize = ?config(rmq_nodes_count, Config),

0 commit comments

Comments
 (0)