7
7
8
8
-module (rabbit_db_queue ).
9
9
10
+ -include_lib (" kernel/include/logger.hrl" ).
11
+ -include_lib (" stdlib/include/assert.hrl" ).
12
+ -include_lib (" stdlib/include/qlc.hrl" ).
13
+
10
14
-include_lib (" khepri/include/khepri.hrl" ).
11
15
-include_lib (" rabbit_common/include/rabbit.hrl" ).
12
- -include_lib (" stdlib/include/qlc.hrl" ).
13
16
-include (" amqqueue.hrl" ).
14
17
15
18
-export ([
@@ -169,7 +172,8 @@ get_all_durable_in_mnesia() ->
169
172
get_all_durable_in_khepri () ->
170
173
list_with_possible_retry_in_khepri (
171
174
fun () ->
172
- ets :tab2list (? KHEPRI_PROJECTION )
175
+ Pattern = amqqueue :pattern_match_on_durable (true ),
176
+ ets :match_object (? KHEPRI_PROJECTION , Pattern )
173
177
end ).
174
178
175
179
-spec get_all_durable_by_type (Type ) -> [Queue ] when
@@ -193,7 +197,7 @@ get_all_durable_by_type_in_mnesia(Type) ->
193
197
rabbit_db :list_in_mnesia (? MNESIA_DURABLE_TABLE , Pattern ).
194
198
195
199
get_all_durable_by_type_in_khepri (Type ) ->
196
- Pattern = amqqueue :pattern_match_on_type (Type ),
200
+ Pattern = amqqueue :pattern_match_on_type_and_durable (Type , true ),
197
201
ets :match_object (? KHEPRI_PROJECTION , Pattern ).
198
202
199
203
% % -------------------------------------------------------------------
@@ -227,7 +231,7 @@ filter_all_durable_in_mnesia(FilterFun) ->
227
231
filter_all_durable_in_khepri (FilterFun ) ->
228
232
ets :foldl (
229
233
fun (Q , Acc0 ) ->
230
- case FilterFun (Q ) of
234
+ case amqqueue : is_durable ( Q ) andalso FilterFun (Q ) of
231
235
true -> [Q | Acc0 ];
232
236
false -> Acc0
233
237
end
@@ -478,12 +482,23 @@ get_in_khepri(Name) ->
478
482
get_durable (Name ) ->
479
483
rabbit_khepri :handle_fallback (
480
484
#{mnesia => fun () -> get_durable_in_mnesia (Name ) end ,
481
- khepri => fun () -> get_in_khepri (Name ) end
485
+ khepri => fun () -> get_durable_in_khepri (Name ) end
482
486
}).
483
487
484
488
get_durable_in_mnesia (Name ) ->
485
489
rabbit_mnesia :dirty_read ({? MNESIA_DURABLE_TABLE , Name }).
486
490
491
+ get_durable_in_khepri (Name ) ->
492
+ case get_in_khepri (Name ) of
493
+ {ok , Queue } = Ret ->
494
+ case amqqueue :is_durable (Queue ) of
495
+ true -> Ret ;
496
+ false -> {error , not_found }
497
+ end ;
498
+ Error ->
499
+ Error
500
+ end .
501
+
487
502
% % -------------------------------------------------------------------
488
503
% % get_many_durable().
489
504
% % -------------------------------------------------------------------
@@ -494,10 +509,17 @@ get_durable_in_mnesia(Name) ->
494
509
495
510
get_many_durable (Names ) when is_list (Names ) ->
496
511
rabbit_khepri :handle_fallback (
497
- #{mnesia => fun () -> get_many_in_ets ( ? MNESIA_DURABLE_TABLE , Names ) end ,
498
- khepri => fun () -> get_many_in_ets ( ? KHEPRI_PROJECTION , Names ) end
512
+ #{mnesia => fun () -> get_many_durable_in_mnesia ( Names ) end ,
513
+ khepri => fun () -> get_many_durable_in_khepri ( Names ) end
499
514
}).
500
515
516
+ get_many_durable_in_mnesia (Names ) ->
517
+ get_many_in_ets (? MNESIA_DURABLE_TABLE , Names ).
518
+
519
+ get_many_durable_in_khepri (Names ) ->
520
+ Queues = get_many_in_ets (? KHEPRI_PROJECTION , Names ),
521
+ [Q || Q <- Queues , amqqueue :is_durable (Q )].
522
+
501
523
% % -------------------------------------------------------------------
502
524
% % update().
503
525
% % -------------------------------------------------------------------
@@ -632,7 +654,9 @@ update_durable_in_khepri(UpdateFun, FilterFun) ->
632
654
fun () ->
633
655
khepri_tx :foreach (Path ,
634
656
fun (Path0 , #{data := Q }) ->
635
- case FilterFun (Q ) of
657
+ DoUpdate = amqqueue :is_durable (Q )
658
+ andalso FilterFun (Q ),
659
+ case DoUpdate of
636
660
true ->
637
661
khepri_tx :put (Path0 , UpdateFun (Q ));
638
662
false ->
@@ -833,7 +857,7 @@ set_in_mnesia(Q) ->
833
857
end ).
834
858
835
859
set_in_mnesia_tx (DurableQ , Q ) ->
836
- case ? amqqueue_is_durable (Q ) of
860
+ case amqqueue : is_durable (Q ) of
837
861
true ->
838
862
ok = mnesia :write (? MNESIA_DURABLE_TABLE , DurableQ , write );
839
863
false ->
@@ -852,8 +876,9 @@ set_in_khepri(Q) ->
852
876
-spec set_many ([Queue ]) -> ok when
853
877
Queue :: amqqueue :amqqueue ().
854
878
% % @doc Writes a list of durable queue records.
855
- % % It is responsibility of the calling function to ensure all records are durable.
856
- % % Once transient entities are deprecated, this is a non-issue.
879
+ % %
880
+ % % It is responsibility of the calling function to ensure all records are
881
+ % % durable.
857
882
% %
858
883
% % @private
859
884
@@ -868,7 +893,10 @@ set_many_in_mnesia(Qs) ->
868
893
% % Just to be nested in forget_node_for_queue
869
894
mnesia :transaction (
870
895
fun () ->
871
- [ok = mnesia :write (? MNESIA_DURABLE_TABLE , Q , write ) || Q <- Qs ],
896
+ [begin
897
+ ? assert (amqqueue :is_durable (Q )),
898
+ ok = mnesia :write (? MNESIA_DURABLE_TABLE , Q , write )
899
+ end || Q <- Qs ],
872
900
ok
873
901
end ),
874
902
ok .
@@ -877,6 +905,7 @@ set_many_in_khepri(Qs) ->
877
905
rabbit_khepri :transaction (
878
906
fun () ->
879
907
[begin
908
+ ? assert (amqqueue :is_durable (Q )),
880
909
Path = khepri_queue_path (amqqueue :get_name (Q )),
881
910
case khepri_tx :put (Path , Q ) of
882
911
ok -> ok ;
@@ -902,7 +931,7 @@ set_many_in_khepri(Qs) ->
902
931
delete_transient (FilterFun ) ->
903
932
rabbit_khepri :handle_fallback (
904
933
#{mnesia => fun () -> delete_transient_in_mnesia (FilterFun ) end ,
905
- khepri => fun () -> ok end
934
+ khepri => fun () -> delete_transient_in_khepri ( FilterFun ) end
906
935
}).
907
936
908
937
delete_transient_in_mnesia (FilterFun ) ->
@@ -944,6 +973,33 @@ partition_queues([Q0,Q1,Q2,Q3,Q4,Q5,Q6,Q7,Q8,Q9 | T]) ->
944
973
partition_queues (T ) ->
945
974
[T ].
946
975
976
+ delete_transient_in_khepri (FilterFun ) ->
977
+ PathPattern = khepri_queues_path () ++
978
+ [? KHEPRI_WILDCARD_STAR ,
979
+ # if_data_matches {
980
+ pattern = amqqueue :pattern_match_on_durable (false )}],
981
+ Ret = rabbit_khepri :fold (
982
+ PathPattern ,
983
+ fun (Path , #{data := Queue }, Acc ) ->
984
+ case FilterFun (Queue ) of
985
+ true ->
986
+ QueueName = khepri_queue_path_to_name (Path ),
987
+ case delete_in_khepri (QueueName , false ) of
988
+ ok -> Acc ;
989
+ Deletions -> [{QueueName , Deletions } | Acc ]
990
+ end ;
991
+ false ->
992
+ Acc
993
+ end
994
+ end , []),
995
+ case Ret of
996
+ {ok , Items } ->
997
+ {QueueNames , Deletions } = lists :unzip (Items ),
998
+ {QueueNames , lists :flatten (Deletions )};
999
+ {error , _ } = Error ->
1000
+ Error
1001
+ end .
1002
+
947
1003
% % -------------------------------------------------------------------
948
1004
% % foreach_transient().
949
1005
% % -------------------------------------------------------------------
@@ -958,7 +1014,7 @@ partition_queues(T) ->
958
1014
foreach_transient (UpdateFun ) ->
959
1015
rabbit_khepri :handle_fallback (
960
1016
#{mnesia => fun () -> foreach_transient_in_mnesia (UpdateFun ) end ,
961
- khepri => fun () -> ok end
1017
+ khepri => fun () -> throw ( not_implemented ) end
962
1018
}).
963
1019
964
1020
foreach_transient_in_mnesia (UpdateFun ) ->
@@ -1001,7 +1057,10 @@ foreach_durable_in_mnesia(UpdateFun, FilterFun) ->
1001
1057
ok .
1002
1058
1003
1059
foreach_durable_in_khepri (UpdateFun , FilterFun ) ->
1004
- Path = khepri_queues_path () ++ [rabbit_khepri :if_has_data_wildcard ()],
1060
+ Path = khepri_queues_path () ++
1061
+ [? KHEPRI_WILDCARD_STAR ,
1062
+ # if_data_matches {
1063
+ pattern = amqqueue :pattern_match_on_durable (true )}],
1005
1064
case rabbit_khepri :filter (Path , fun (_ , #{data := Q }) ->
1006
1065
FilterFun (Q )
1007
1066
end ) of
@@ -1190,3 +1249,6 @@ khepri_queues_path() ->
1190
1249
1191
1250
khepri_queue_path (# resource {virtual_host = VHost , name = Name }) ->
1192
1251
[? MODULE , queues , VHost , Name ].
1252
+
1253
+ khepri_queue_path_to_name ([? MODULE , queues , VHost , Name ]) ->
1254
+ rabbit_misc :r (VHost , queue , Name ).
0 commit comments