Skip to content

Commit 2025af8

Browse files
committed
QQ hi/lo priority queue
1 parent c22205d commit 2025af8

11 files changed

+484
-74
lines changed

deps/rabbit/BUILD.bazel

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,15 @@ rabbitmq_suite(
729729
],
730730
)
731731

732+
rabbitmq_suite(
733+
name = "rabbit_fifo_q_SUITE",
734+
size = "small",
735+
deps = [
736+
"@proper//:erlang_app",
737+
"//deps/rabbit_common:erlang_app",
738+
],
739+
)
740+
732741
rabbitmq_integration_suite(
733742
name = "rabbit_fifo_dlx_integration_SUITE",
734743
size = "medium",

deps/rabbit/app.bzl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ def all_beam_files(name = "all_beam_files"):
147147
"src/rabbit_fifo_dlx_sup.erl",
148148
"src/rabbit_fifo_dlx_worker.erl",
149149
"src/rabbit_fifo_index.erl",
150+
"src/rabbit_fifo_q.erl",
150151
"src/rabbit_fifo_v0.erl",
151152
"src/rabbit_fifo_v1.erl",
152153
"src/rabbit_fifo_v3.erl",
@@ -409,6 +410,7 @@ def all_test_beam_files(name = "all_test_beam_files"):
409410
"src/rabbit_fifo_dlx_sup.erl",
410411
"src/rabbit_fifo_dlx_worker.erl",
411412
"src/rabbit_fifo_index.erl",
413+
"src/rabbit_fifo_q.erl",
412414
"src/rabbit_fifo_v0.erl",
413415
"src/rabbit_fifo_v1.erl",
414416
"src/rabbit_fifo_v3.erl",
@@ -691,6 +693,7 @@ def all_srcs(name = "all_srcs"):
691693
"src/rabbit_fifo_dlx_sup.erl",
692694
"src/rabbit_fifo_dlx_worker.erl",
693695
"src/rabbit_fifo_index.erl",
696+
"src/rabbit_fifo_q.erl",
694697
"src/rabbit_fifo_v0.erl",
695698
"src/rabbit_fifo_v1.erl",
696699
"src/rabbit_fifo_v3.erl",
@@ -2144,3 +2147,13 @@ def test_suite_beam_files(name = "test_suite_beam_files"):
21442147
erlc_opts = "//:test_erlc_opts",
21452148
deps = ["//deps/amqp_client:erlang_app"],
21462149
)
2150+
erlang_bytecode(
2151+
name = "rabbit_fifo_q_SUITE_beam_files",
2152+
testonly = True,
2153+
srcs = ["test/rabbit_fifo_q_SUITE.erl"],
2154+
outs = ["test/rabbit_fifo_q_SUITE.beam"],
2155+
hdrs = ["src/rabbit_fifo.hrl"],
2156+
app_name = "rabbit",
2157+
erlc_opts = "//:test_erlc_opts",
2158+
deps = ["@proper//:erlang_app"],
2159+
)

deps/rabbit/src/rabbit_fifo.erl

Lines changed: 57 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
-dialyzer(no_improper_lists).
1515

1616
-include("rabbit_fifo.hrl").
17-
-include_lib("rabbit_common/include/rabbit.hrl").
1817

1918
-define(STATE, ?MODULE).
2019

@@ -299,7 +298,9 @@ apply(#{index := Idx} = Meta,
299298
credit = increase_credit(Con0, 1)},
300299
State1 = State0#?STATE{ra_indexes = rabbit_fifo_index:delete(OldIdx,
301300
Indexes0),
302-
messages = lqueue:in(?MSG(Idx, Header), Messages),
301+
messages = rabbit_fifo_q:in(lo,
302+
?MSG(Idx, Header),
303+
Messages),
303304
enqueue_count = EnqCount + 1},
304305
State2 = update_or_remove_con(Meta, ConsumerKey, Con, State1),
305306
{State, Ret, Effs} = checkout(Meta, State0, State2, []),
@@ -566,7 +567,7 @@ apply(#{index := Index}, #purge{},
566567
end, Indexes0, Returns)
567568
end,
568569
State1 = State0#?STATE{ra_indexes = Indexes,
569-
messages = lqueue:new(),
570+
messages = rabbit_fifo_q:new(),
570571
messages_total = Total - NumReady,
571572
returns = lqueue:new(),
572573
msg_bytes_enqueue = 0
@@ -736,7 +737,11 @@ apply(_Meta, Cmd, State) ->
736737
rabbit_log:debug("rabbit_fifo: unhandled command ~W", [Cmd, 10]),
737738
{State, ok, []}.
738739

739-
convert_v3_to_v4(#{system_time := Ts}, #rabbit_fifo{consumers = Consumers0} = StateV3) ->
740+
convert_v3_to_v4(#{system_time := Ts},
741+
StateV3) ->
742+
Messages0 = rabbit_fifo_v3:get_field(messages, StateV3),
743+
Consumers0 = rabbit_fifo_v3:get_field(consumers, StateV3),
744+
Messages = rabbit_fifo_q:from_lqueue(Messages0),
740745
Consumers = maps:map(
741746
fun (_CKey, #consumer{checked_out = Ch0} = C) ->
742747
Ch = maps:map(
@@ -745,7 +750,23 @@ convert_v3_to_v4(#{system_time := Ts}, #rabbit_fifo{consumers = Consumers0} = St
745750
end, Ch0),
746751
C#consumer{checked_out = Ch}
747752
end, Consumers0),
748-
StateV3#?MODULE{consumers = Consumers}.
753+
#?MODULE{cfg = rabbit_fifo_v3:get_field(cfg, StateV3),
754+
messages = Messages,
755+
messages_total = rabbit_fifo_v3:get_field(messages_total, StateV3),
756+
returns = rabbit_fifo_v3:get_field(returns, StateV3),
757+
enqueue_count = rabbit_fifo_v3:get_field(enqueue_count, StateV3),
758+
enqueuers = rabbit_fifo_v3:get_field(enqueuers, StateV3),
759+
ra_indexes = rabbit_fifo_v3:get_field(ra_indexes, StateV3),
760+
release_cursors = rabbit_fifo_v3:get_field(release_cursors, StateV3),
761+
consumers = Consumers,
762+
% consumers that require further service are queued here
763+
service_queue = rabbit_fifo_v3:get_field(service_queue, StateV3),
764+
dlx = rabbit_fifo_v3:get_field(dlx, StateV3),
765+
msg_bytes_enqueue = rabbit_fifo_v3:get_field(msg_bytes_enqueue, StateV3),
766+
msg_bytes_checkout = rabbit_fifo_v3:get_field(msg_bytes_checkout, StateV3),
767+
waiting_consumers = rabbit_fifo_v3:get_field(waiting_consumers, StateV3),
768+
last_active = rabbit_fifo_v3:get_field(last_active, StateV3),
769+
msg_cache = rabbit_fifo_v3:get_field(msg_cache, StateV3)}.
749770

750771
purge_node(Meta, Node, State, Effects) ->
751772
lists:foldl(fun(Pid, {S0, E0}) ->
@@ -1348,7 +1369,7 @@ is_v4() ->
13481369

13491370
messages_ready(#?STATE{messages = M,
13501371
returns = R}) ->
1351-
lqueue:len(M) + lqueue:len(R).
1372+
rabbit_fifo_q:len(M) + lqueue:len(R).
13521373

13531374
messages_total(#?STATE{messages_total = Total,
13541375
dlx = DlxState}) ->
@@ -1599,19 +1620,6 @@ drop_head(#?STATE{ra_indexes = Indexes0} = State0, Effects) ->
15991620
{State0, Effects}
16001621
end.
16011622

1602-
maybe_set_msg_ttl(#basic_message{content = #content{properties = none}},
1603-
RaCmdTs, Header,
1604-
#?STATE{cfg = #cfg{msg_ttl = PerQueueMsgTTL}}) ->
1605-
update_expiry_header(RaCmdTs, PerQueueMsgTTL, Header);
1606-
maybe_set_msg_ttl(#basic_message{content = #content{properties = Props}},
1607-
RaCmdTs, Header,
1608-
#?STATE{cfg = #cfg{msg_ttl = PerQueueMsgTTL}}) ->
1609-
%% rabbit_quorum_queue will leave the properties decoded if and only if
1610-
%% per message message TTL is set.
1611-
%% We already check in the channel that expiration must be valid.
1612-
{ok, PerMsgMsgTTL} = rabbit_basic:parse_expiration(Props),
1613-
TTL = min(PerMsgMsgTTL, PerQueueMsgTTL),
1614-
update_expiry_header(RaCmdTs, TTL, Header);
16151623
maybe_set_msg_ttl(Msg, RaCmdTs, Header,
16161624
#?STATE{cfg = #cfg{msg_ttl = MsgTTL}}) ->
16171625
case mc:is(Msg) of
@@ -1673,10 +1681,11 @@ maybe_enqueue(RaftIdx, Ts, undefined, undefined, RawMsg, Effects,
16731681
Size = message_size(RawMsg),
16741682
Header = maybe_set_msg_ttl(RawMsg, Ts, Size, State0),
16751683
Msg = ?MSG(RaftIdx, Header),
1684+
PTag = priority_tag(RawMsg),
16761685
State = State0#?STATE{msg_bytes_enqueue = Enqueue + Size,
16771686
enqueue_count = EnqCount + 1,
16781687
messages_total = Total + 1,
1679-
messages = lqueue:in(Msg, Messages)
1688+
messages = rabbit_fifo_q:in(PTag, Msg, Messages)
16801689
},
16811690
{ok, State, Effects};
16821691
maybe_enqueue(RaftIdx, Ts, From, MsgSeqNo, RawMsg, Effects0,
@@ -1704,10 +1713,11 @@ maybe_enqueue(RaftIdx, Ts, From, MsgSeqNo, RawMsg, Effects0,
17041713
false ->
17051714
undefined
17061715
end,
1716+
PTag = priority_tag(RawMsg),
17071717
State = State0#?STATE{msg_bytes_enqueue = Enqueue + Size,
17081718
enqueue_count = EnqCount + 1,
17091719
messages_total = Total + 1,
1710-
messages = lqueue:in(Msg, Messages),
1720+
messages = rabbit_fifo_q:in(PTag, Msg, Messages),
17111721
enqueuers = Enqueuers0#{From => Enq},
17121722
msg_cache = MsgCache
17131723
},
@@ -1824,10 +1834,10 @@ update_smallest_raft_index(IncomingRaftIdx, Reply,
18241834
#?STATE{cfg = Cfg,
18251835
release_cursors = Cursors0} = State0,
18261836
Effects) ->
1827-
Total = messages_total(State0),
1837+
% Total = messages_total(State0),
18281838
%% TODO: optimise
18291839
case smallest_raft_index(State0) of
1830-
undefined when Total == 0 ->
1840+
undefined ->
18311841
% there are no messages on queue anymore and no pending enqueues
18321842
% we can forward release_cursor all the way until
18331843
% the last received command, hooray
@@ -1838,8 +1848,8 @@ update_smallest_raft_index(IncomingRaftIdx, Reply,
18381848
release_cursors = lqueue:new(),
18391849
enqueue_count = 0},
18401850
{State, Reply, Effects ++ [{release_cursor, IncomingRaftIdx, State}]};
1841-
undefined ->
1842-
{State0, Reply, Effects};
1851+
% undefined ->
1852+
% {State0, Reply, Effects};
18431853
Smallest when is_integer(Smallest) ->
18441854
case find_next_cursor(Smallest, Cursors0) of
18451855
empty ->
@@ -2066,10 +2076,10 @@ take_next_msg(#?STATE{returns = Returns0,
20662076
{{value, NextMsg}, Returns} ->
20672077
{NextMsg, State#?STATE{returns = Returns}};
20682078
{empty, _} ->
2069-
case lqueue:out(Messages0) of
2079+
case rabbit_fifo_q:out(Messages0) of
20702080
{empty, _} ->
20712081
empty;
2072-
{{value, ?MSG(RaftIdx, _) = Msg}, Messages} ->
2082+
{_P, ?MSG(RaftIdx, _) = Msg, Messages} ->
20732083
%% add index here
20742084
Indexes = rabbit_fifo_index:append(RaftIdx, Indexes0),
20752085
{Msg, State#?STATE{messages = Messages,
@@ -2081,7 +2091,7 @@ get_next_msg(#?STATE{returns = Returns0,
20812091
messages = Messages0}) ->
20822092
case lqueue:get(Returns0, empty) of
20832093
empty ->
2084-
lqueue:get(Messages0, empty);
2094+
rabbit_fifo_q:get(Messages0);
20852095
Msg ->
20862096
Msg
20872097
end.
@@ -2176,7 +2186,7 @@ checkout_one(#{system_time := Ts} = Meta, ExpiredMsg0, InitState0, Effects0) ->
21762186
checkout_one(Meta, ExpiredMsg,
21772187
InitState#?STATE{service_queue = SQ1}, Effects1);
21782188
{empty, _} ->
2179-
case lqueue:len(Messages0) of
2189+
case rabbit_fifo_q:len(Messages0) of
21802190
0 ->
21812191
{nochange, ExpiredMsg, InitState, Effects1};
21822192
_ ->
@@ -2410,9 +2420,10 @@ normalize(#?STATE{ra_indexes = _Indexes,
24102420
release_cursors = Cursors,
24112421
dlx = DlxState} = State) ->
24122422
State#?STATE{returns = lqueue:from_list(lqueue:to_list(Returns)),
2413-
messages = lqueue:from_list(lqueue:to_list(Messages)),
2414-
release_cursors = lqueue:from_list(lqueue:to_list(Cursors)),
2415-
dlx = rabbit_fifo_dlx:normalize(DlxState)}.
2423+
messages = rabbit_fifo_q:normalize(Messages,
2424+
rabbit_fifo_q:new()),
2425+
release_cursors = lqueue:from_list(lqueue:to_list(Cursors)),
2426+
dlx = rabbit_fifo_dlx:normalize(DlxState)}.
24162427

24172428
is_over_limit(#?STATE{cfg = #cfg{max_length = undefined,
24182429
max_bytes = undefined}}) ->
@@ -2520,9 +2531,6 @@ add_bytes_return(Header,
25202531
State#?STATE{msg_bytes_checkout = Checkout - Size,
25212532
msg_bytes_enqueue = Enqueue + Size}.
25222533

2523-
message_size(#basic_message{content = Content}) ->
2524-
#content{payload_fragments_rev = PFR} = Content,
2525-
iolist_size(PFR);
25262534
message_size(B) when is_binary(B) ->
25272535
byte_size(B);
25282536
message_size(Msg) ->
@@ -2644,12 +2652,7 @@ smallest_raft_index(#?STATE{messages = Messages,
26442652
ra_indexes = Indexes,
26452653
dlx = DlxState}) ->
26462654
SmallestDlxRaIdx = rabbit_fifo_dlx:smallest_raft_index(DlxState),
2647-
SmallestMsgsRaIdx = case lqueue:get(Messages, undefined) of
2648-
?MSG(I, _) when is_integer(I) ->
2649-
I;
2650-
_ ->
2651-
undefined
2652-
end,
2655+
SmallestMsgsRaIdx = rabbit_fifo_q:get_lowest_index(Messages),
26532656
SmallestRaIdx = rabbit_fifo_index:smallest(Indexes),
26542657
lists:min([SmallestDlxRaIdx, SmallestMsgsRaIdx, SmallestRaIdx]).
26552658

@@ -2791,3 +2794,16 @@ maps_search(Pred, {K, V, I}) ->
27912794
end;
27922795
maps_search(Pred, Map) when is_map(Map) ->
27932796
maps_search(Pred, maps:next(maps:iterator(Map))).
2797+
2798+
priority_tag(Msg) ->
2799+
case mc:is(Msg) of
2800+
true ->
2801+
case mc:priority(Msg) of
2802+
P when P > 4 ->
2803+
hi;
2804+
_ ->
2805+
lo
2806+
end;
2807+
false ->
2808+
lo
2809+
end.

deps/rabbit/src/rabbit_fifo.hrl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@
181181
-record(rabbit_fifo,
182182
{cfg :: #cfg{},
183183
% unassigned messages
184-
messages = lqueue:new() :: lqueue:lqueue(msg()),
184+
messages = rabbit_fifo_q:new() :: rabbit_fifo_q:state(),
185185
messages_total = 0 :: non_neg_integer(),
186186
% queue of returned msg_in_ids - when checking out it picks from
187187
returns = lqueue:new() :: lqueue:lqueue(term()),

0 commit comments

Comments
 (0)