diff options
author | Jean-Sébastien Pédron <jean-sebastien@rabbitmq.com> | 2021-08-19 16:45:24 +0200 |
---|---|---|
committer | mergify-bot <noreply@mergify.io> | 2021-08-19 15:53:42 +0000 |
commit | b3899d73121e35222a71e8d577f20f0a0076d615 (patch) | |
tree | 97a7b93de364477cc1ff5190f5a5f7aaca1d81c2 | |
parent | 9ea36a295efe142a49e45f5a64986b1415c90a2d (diff) | |
download | rabbitmq-server-git-mergify/bp/v3.8.x/pr-3324.tar.gz |
rabbit_{connection,channel}_tracking: Fix race condition in list()mergify/bp/v3.8.x/pr-3324
The table might not exist yet (or is already gone) between the time
rabbit_nodes:all_running() runs and returns a specific node, and
mnesia:dirty_match_object() is called for that node's table.
This seems to happen frequently in CI.
(cherry picked from commit 0b1942bdc0938cb6018ef0e8eede164a0d4e4644)
-rw-r--r-- | deps/rabbit/src/rabbit_channel_tracking.erl | 13 | ||||
-rw-r--r-- | deps/rabbit/src/rabbit_connection_tracking.erl | 16 |
2 files changed, 27 insertions, 2 deletions
diff --git a/deps/rabbit/src/rabbit_channel_tracking.erl b/deps/rabbit/src/rabbit_channel_tracking.erl index 78ed80971a..323ddf1bab 100644 --- a/deps/rabbit/src/rabbit_channel_tracking.erl +++ b/deps/rabbit/src/rabbit_channel_tracking.erl @@ -179,7 +179,18 @@ list() -> lists:foldl( fun (Node, Acc) -> Tab = tracked_channel_table_name_for(Node), - Acc ++ mnesia:dirty_match_object(Tab, #tracked_channel{_ = '_'}) + try + Acc ++ + mnesia:dirty_match_object(Tab, #tracked_channel{_ = '_'}) + catch + exit:{aborted, {no_exists, [Tab, _]}} -> + %% The table might not exist yet (or is already gone) + %% between the time rabbit_nodes:all_running() runs and + %% returns a specific node, and + %% mnesia:dirty_match_object() is called for that node's + %% table. + Acc + end end, [], rabbit_nodes:all_running()). -spec list_of_user(rabbit_types:username()) -> [rabbit_types:tracked_channel()]. diff --git a/deps/rabbit/src/rabbit_connection_tracking.erl b/deps/rabbit/src/rabbit_connection_tracking.erl index fd37ee049b..10354925ab 100644 --- a/deps/rabbit/src/rabbit_connection_tracking.erl +++ b/deps/rabbit/src/rabbit_connection_tracking.erl @@ -351,7 +351,18 @@ list() -> lists:foldl( fun (Node, Acc) -> Tab = tracked_connection_table_name_for(Node), - Acc ++ mnesia:dirty_match_object(Tab, #tracked_connection{_ = '_'}) + try + Acc ++ + mnesia:dirty_match_object(Tab, #tracked_connection{_ = '_'}) + catch + exit:{aborted, {no_exists, [Tab, _]}} -> + %% The table might not exist yet (or is already gone) + %% between the time rabbit_nodes:all_running() runs and + %% returns a specific node, and + %% mnesia:dirty_match_object() is called for that node's + %% table. + Acc + end end, [], rabbit_nodes:all_running()). -spec count() -> non_neg_integer(). @@ -360,6 +371,9 @@ count() -> lists:foldl( fun (Node, Acc) -> Tab = tracked_connection_table_name_for(Node), + %% mnesia:table_info() returns 0 if the table doesn't exist. We + %% don't need the same kind of protection as the list() function + %% above. Acc + mnesia:table_info(Tab, size) end, 0, rabbit_nodes:all_running()). |