Skip to content

Commit ba22919

Browse files
committed
Khepri: Use the queue projection in rabbit_db_queue
The `rabbit_khepri_queue` projection ETS table can be used in the read-only functions in `rabbit_db_queue` when Khepri is enabled. This fixes performance issues when looking up queues for message delivery with Khepri enabled.
1 parent fc13308 commit ba22919

File tree

1 file changed

+29
-37
lines changed

1 file changed

+29
-37
lines changed

deps/rabbit/src/rabbit_db_queue.erl

Lines changed: 29 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@
7777
-define(MNESIA_TABLE, rabbit_queue).
7878
-define(MNESIA_DURABLE_TABLE, rabbit_durable_queue).
7979

80+
-define(KHEPRI_PROJECTION, rabbit_khepri_queue).
81+
8082
%% -------------------------------------------------------------------
8183
%% get_all().
8284
%% -------------------------------------------------------------------
@@ -105,7 +107,7 @@ get_all_in_mnesia() ->
105107
get_all_in_khepri() ->
106108
list_with_possible_retry_in_khepri(
107109
fun() ->
108-
rabbit_db:list_in_khepri(khepri_queues_path() ++ [rabbit_khepri:if_has_data_wildcard()])
110+
ets:tab2list(?KHEPRI_PROJECTION)
109111
end).
110112

111113
-spec get_all(VHostName) -> [Queue] when
@@ -134,7 +136,8 @@ get_all_in_mnesia(VHostName) ->
134136
get_all_in_khepri(VHostName) ->
135137
list_with_possible_retry_in_khepri(
136138
fun() ->
137-
rabbit_db:list_in_khepri(khepri_queues_path() ++ [VHostName, rabbit_khepri:if_has_data_wildcard()])
139+
Pattern = amqqueue:pattern_match_on_name(rabbit_misc:r(VHostName, queue)),
140+
ets:match_object(?KHEPRI_PROJECTION, Pattern)
138141
end).
139142

140143
%% -------------------------------------------------------------------
@@ -165,7 +168,7 @@ get_all_durable_in_mnesia() ->
165168
get_all_durable_in_khepri() ->
166169
list_with_possible_retry_in_khepri(
167170
fun() ->
168-
rabbit_db:list_in_khepri(khepri_queues_path() ++ [rabbit_khepri:if_has_data_wildcard()])
171+
ets:tab2list(?KHEPRI_PROJECTION)
169172
end).
170173

171174
-spec get_all_durable_by_type(Type) -> [Queue] when
@@ -190,7 +193,7 @@ get_all_durable_by_type_in_mnesia(Type) ->
190193

191194
get_all_durable_by_type_in_khepri(Type) ->
192195
Pattern = amqqueue:pattern_match_on_type(Type),
193-
rabbit_db:list_in_khepri(khepri_queues_path() ++ [rabbit_khepri:if_has_data([?KHEPRI_WILDCARD_STAR_STAR, #if_data_matches{pattern = Pattern}])]).
196+
ets:match_object(?KHEPRI_PROJECTION, Pattern).
194197

195198
%% -------------------------------------------------------------------
196199
%% filter_all_durable().
@@ -221,17 +224,14 @@ filter_all_durable_in_mnesia(FilterFun) ->
221224
end).
222225

223226
filter_all_durable_in_khepri(FilterFun) ->
224-
Path = khepri_queues_path() ++ [rabbit_khepri:if_has_data_wildcard()],
225-
{ok, Res} = rabbit_khepri:fold(
226-
Path,
227-
fun(_, #{data := Q}, Acc0) ->
228-
case FilterFun(Q) of
229-
true -> [Q | Acc0];
230-
false -> Acc0
231-
end
232-
end,
233-
[]),
234-
Res.
227+
ets:foldl(
228+
fun(Q, Acc0) ->
229+
case FilterFun(Q) of
230+
true -> [Q | Acc0];
231+
false -> Acc0
232+
end
233+
end,
234+
[], ?KHEPRI_PROJECTION).
235235

236236
%% -------------------------------------------------------------------
237237
%% list().
@@ -256,12 +256,8 @@ list_in_mnesia() ->
256256
mnesia:dirty_all_keys(?MNESIA_TABLE).
257257

258258
list_in_khepri() ->
259-
case rabbit_khepri:match(khepri_queues_path() ++ [rabbit_khepri:if_has_data_wildcard()]) of
260-
{ok, Map} ->
261-
maps:fold(fun(_K, Q, Acc) -> [amqqueue:get_name(Q) | Acc] end, [], Map);
262-
_ ->
263-
[]
264-
end.
259+
Pattern = amqqueue:pattern_match_on_name('$1'),
260+
ets:select(?KHEPRI_PROJECTION, [{Pattern, [], ['$1']}]).
265261

266262
%% -------------------------------------------------------------------
267263
%% count().
@@ -286,7 +282,7 @@ count_in_mnesia() ->
286282
mnesia:table_info(?MNESIA_TABLE, size).
287283

288284
count_in_khepri() ->
289-
rabbit_khepri:count_children(khepri_queues_path() ++ [?KHEPRI_WILDCARD_STAR]).
285+
ets:info(?KHEPRI_PROJECTION, size).
290286

291287
-spec count(VHostName) -> Count when
292288
VHostName :: vhost:name(),
@@ -327,10 +323,8 @@ list_for_count_in_mnesia(VHostName) ->
327323
end).
328324

329325
list_for_count_in_khepri(VHostName) ->
330-
list_with_possible_retry_in_khepri(
331-
fun() ->
332-
rabbit_khepri:count_children(khepri_queues_path() ++ [VHostName])
333-
end).
326+
Pattern = amqqueue:pattern_match_on_name(rabbit_misc:r(VHostName, queue)),
327+
ets:select_count(?KHEPRI_PROJECTION, [{Pattern, [], [true]}]).
334328

335329
%% -------------------------------------------------------------------
336330
%% delete().
@@ -422,20 +416,18 @@ get_many(Names) when is_list(Names) ->
422416
khepri => fun() -> get_many_in_khepri(Names) end
423417
}).
424418

425-
get_many_in_mnesia(Table, [Name]) ->
426-
ets:lookup(Table, Name);
427-
get_many_in_mnesia(Table, Names) when is_list(Names) ->
419+
get_many_in_mnesia(Table, Names) ->
428420
%% Normally we'd call mnesia:dirty_read/1 here, but that is quite
429421
%% expensive for reasons explained in rabbit_mnesia:dirty_read/1.
430-
lists:append([ets:lookup(Table, Name) || Name <- Names]).
422+
get_many_in_ets(Table, Names).
431423

432424
get_many_in_khepri(Names) when is_list(Names) ->
433-
lists:foldl(fun(Name, Acc) ->
434-
case get_in_khepri(Name) of
435-
{ok, X} -> [X | Acc];
436-
_ -> Acc
437-
end
438-
end, [], Names).
425+
get_many_in_ets(?KHEPRI_PROJECTION, Names).
426+
427+
get_many_in_ets(Table, [Name]) ->
428+
ets:lookup(Table, Name);
429+
get_many_in_ets(Table, Names) when is_list(Names) ->
430+
lists:append([ets:lookup(Table, Name) || Name <- Names]).
439431

440432
%% -------------------------------------------------------------------
441433
%% get().
@@ -656,7 +648,7 @@ exists_in_mnesia(QName) ->
656648
ets:member(?MNESIA_TABLE, QName).
657649

658650
exists_in_khepri(QName) ->
659-
ets:member(rabbit_khepri_queue, QName).
651+
ets:member(?KHEPRI_PROJECTION, QName).
660652

661653
%% -------------------------------------------------------------------
662654
%% exists().

0 commit comments

Comments
 (0)