Skip to content

Commit ba2388b

Browse files
kjnilssonansdthe-mikedavis
committed
Quorum queues v4 (#10637)
This commit contains the following new quorum queue features: * Fair share high/low priorities * SAC consumers honour consumer priorities * Credited consumer refactoring to meet AMQP requirements. * Use checkpoints feature to reduce memory use for queues with long backlogs * Consumer cancel option that immediately removes consumer and returns all pending messages. * More compact commands of the most common commands such as enqueue, settle and credit * Correctly track the delivery-count to be compatible with the AMQP spec * Support the "modified" AMQP 1.0 outcome better. Commits: * Quorum queues v4 scaffolding. Create the new version but not including any changes yet. QQ: force delete followers after leader has terminated. Also try a longer sleep for mqtt_shared_SUITE so that the delete operation stands a chance to time out and move on to the forced deletion stage. In some mixed machine version scenarios some followers will never apply the poison pill command so we may as well force delete them just in case. QQ: skip test in amqp_client that cannot pass with mixed machine versions QQ: remove dead code Code relating to prior machine versions and state conversions. rabbit_fifo_prop_SUITE fixes * QQ: add v4 ff and new more compact enqueue command. Also update rabbit_fifo_* suites to test more relevant code versions where applicable. QQ: always use the updated credit mode format QQv4: use more compact consumer reference in settle, credit, return This introudces a new type: consumer_key() which is either the consumer_id or the raft index the checkout was processed at. If the consumer is using one of the updated credit spec formats rabbit_fifo will use the raft index as the primary key for the consumer such that the rabbit fifo client can then use the more space efficient integer index instead of the full consumer id in subsequent commands. There is compatibility code to still accept the consumer id in settle, return, discard and credit commands but this is slighlyt slower and of course less space efficient. The old form will be used in cases where the fifo client may have already remove the local consumer state (as happens after a cancel). Lots of test refactorings of the rabbit_fifo_SUITE to begin to use the new forms. * More test refactoring and new API fixes rabbit_fifo_prop_SUITE refactoring and other fixes. * First pass SAC consumer priority implementation. Single active consumers will be activated if they have a higher priority than the currently active consumer. if the currently active consumer has pending messages, no further messages will be assigned to the consumer and the activation of the new consumer will happen once all pending messages are settled. This is to ensure processing order. Consumers with the same priority will internally be ordered to favour those with credit then those that attached first. QQ: add SAC consumer priority integration tests QQ: add check for ff in tests * QQ: add new consumer cancel option: 'remove' This option immediately removes and returns all messages for a consumer instead of the softer 'cancel' option which keeps the consumer around until all pending messages have been either settled or returned. This involves a change to the rabbit_queue_type:cancel/5 API to rabbit_queue_type:cancel/3. * QQ: capture checked out time for each consumer message. This will form the basis for queue initiated consumer timeouts. * QQ: Refactor to use the new ra_machine:handle_aux/5 API Instead of the old ra_machine:handle_aux/6 callback. * QQ hi/lo priority queue * QQ: Avoid using mc:size/1 inside rabbit_fifo As we dont want to depend on external functions for things that may change the state of the queue. * QQ bug fix: Maintain order when returning multiple Prior to this commit, quorum queues requeued messages in an undefined order, which is wrong. This commit fixes this bug and requeues messages always in the order as nacked / rejected / released by the client. We ensure that order of requeues is deterministic from the client's point of view and doesn't depend on whether the quorum queue soft limit was exceeded temporarily. So, even when rabbit_fifo_client batches requeues, the order as nacked by the client is still maintained. * Simplify * Add rabbit_quorum_queue:file_handle* functions back. For backwards compat. * dialyzer fix * dynamic_qq_SUITE: avoid mixed versions failure. * QQ: track number of requeues for message. To be able to calculate the correct value for the AMQP delivery_count header we need to be able to distinguish between messages that were "released" or returned in QQ speak and those that were returned due to errors such as channel termination. This commit implement such tracking as well as the calculation of a new mc annotations `delivery_count` that AMQP makes use of to set the header value accordingly. * Use QQ consumer removal when AMQP client detaches This enables us to unskip some AMQP tests. * Use AMQP address v2 in fsharp-tests * QQ: track number of requeues for message. To be able to calculate the correct value for the AMQP delivery_count header we need to be able to distinguish between messages that were "released" or returned in QQ speak and those that were returned due to errors such as channel termination. This commit implement such tracking as well as the calculation of a new mc annotations `delivery_count` that AMQP makes use of to set the header value accordingly. * rabbit_fifo: Use Ra checkpoints * quorum queues: Use a custom interval for checkpoints * rabbit_fifo_SUITE: List actual effects in ?ASSERT_EFF failure * QQ: Checkpoints modifications * fixes * QQ: emit release cursors on tick for followers and leaders else followers could end up holding on to segments a bit longer after traffic stops. * Support draining a QQ SAC waiting consumer By issuing drain=true, the client says "either send a transfer or a flow frame". Since there are no messages to send to an inactive consumer, the sending queue should advance the delivery-count consuming all link-credit and send a credit_reply with drain=true to the session proc which causes the session proc to send a flow frame to the client. * Extract applying #credit{} cmd into 2 functions This commit is only refactoring and doesn't change any behaviour. * Fix default priority level Prior to this commit, when a message didn't have a priority level set, it got enqueued as high prio. This is wrong because the default priority is 4 and "for example, if 2 distinct priorities are implemented, then levels 0 to 4 are equivalent, and levels 5 to 9 are equivalent and levels 4 and 5 are distinct." Hence, by default a message without priority set, must be enqueued as low prio. * bazel run gazelle * Avoid deprecated time unit * Fix aux_test * Delete dead code * Fix rabbit_fifo_q:get_lowest_index/1 * Delete unused normalize functions * Generate less garbage * Add integration test for QQ SAC with consumer priority * Improve readability * Change modified outcome behaviour With the new quorum queue v4 improvements where a requeue counter was added in addition to the quorum queue delivery counter, the following sentence from #6292 (comment) doesn't apply anymore: > Also the case where delivery_failed=false|undefined requires the release of the > message without incrementing the delivery_count. Again this is not something > that our queues are able to do so again we have to reject without requeue. Therefore, we simplify the modified outcome behaviour: RabbitMQ will from now on only discard the message if the modified's undeliverable-here field is true. * Introduce single feature flag rabbitmq_4.0.0 ## What? Merge all feature flags introduced in RabbitMQ 4.0.0 into a single feature flag called rabbitmq_4.0.0. ## Why? 1. This fixes the crash in #10637 (comment) 2. It's better user experience. * QQ: expose priority metrics in UI * Enable skipped test after rebasing onto main * QQ: add new command "modify" to better handle AMQP modified outcomes. This new command can be used to annotate returned or rejected messages. This commit also retains the delivery-count across dead letter boundaries such that the AMQP header delivery-count field can now include _all_ failed deliver attempts since the message was originally received. Internally the quorum queue has moved it's delivery_count header to only track the AMQP protocol delivery attempts and now introduces a new acquired_count to track all message acquisitions by consumers. * Type tweaks and naming * Add test for modified outcome with classic queue * Add test routing on message-annotations in modified outcome * Skip tests in mixed version tests Skip tests in mixed version tests because feature flag rabbitmq_4.0.0 is needed for the new #modify{} Ra command being sent to quorum queues. --------- Co-authored-by: David Ansari <[email protected]> Co-authored-by: Michael Davis <[email protected]> (cherry picked from commit 194d4ba)
1 parent cc8bc22 commit ba2388b

40 files changed

+8107
-3046
lines changed

deps/amqp10_client/src/amqp10_msg.erl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,8 @@ header(first_acquirer = K,
193193
header(delivery_count = K,
194194
#amqp10_msg{header = #'v1_0.header'{delivery_count = D}}) ->
195195
header_value(K, D);
196-
header(K, #amqp10_msg{header = undefined}) -> header_value(K, undefined).
196+
header(K, #amqp10_msg{header = undefined}) ->
197+
header_value(K, undefined).
197198

198199
-spec delivery_annotations(amqp10_msg()) -> #{annotations_key() => any()}.
199200
delivery_annotations(#amqp10_msg{delivery_annotations = undefined}) ->

deps/rabbit/BUILD.bazel

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,9 @@ rabbitmq_suite(
705705
rabbitmq_suite(
706706
name = "rabbit_fifo_int_SUITE",
707707
size = "medium",
708+
additional_beam = [
709+
":test_test_util_beam",
710+
],
708711
deps = [
709712
"//deps/rabbit_common:erlang_app",
710713
"@aten//:erlang_app",
@@ -722,6 +725,7 @@ rabbitmq_suite(
722725
],
723726
deps = [
724727
"//deps/rabbit_common:erlang_app",
728+
"@meck//:erlang_app",
725729
"@proper//:erlang_app",
726730
"@ra//:erlang_app",
727731
],
@@ -735,6 +739,15 @@ rabbitmq_suite(
735739
],
736740
)
737741

742+
rabbitmq_suite(
743+
name = "rabbit_fifo_q_SUITE",
744+
size = "small",
745+
deps = [
746+
"//deps/rabbit_common:erlang_app",
747+
"@proper//:erlang_app",
748+
],
749+
)
750+
738751
rabbitmq_integration_suite(
739752
name = "rabbit_fifo_dlx_integration_SUITE",
740753
size = "medium",

deps/rabbit/app.bzl

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,10 @@ def all_beam_files(name = "all_beam_files"):
146146
"src/rabbit_fifo_dlx_sup.erl",
147147
"src/rabbit_fifo_dlx_worker.erl",
148148
"src/rabbit_fifo_index.erl",
149+
"src/rabbit_fifo_q.erl",
149150
"src/rabbit_fifo_v0.erl",
150151
"src/rabbit_fifo_v1.erl",
152+
"src/rabbit_fifo_v3.erl",
151153
"src/rabbit_file.erl",
152154
"src/rabbit_global_counters.erl",
153155
"src/rabbit_guid.erl",
@@ -399,8 +401,10 @@ def all_test_beam_files(name = "all_test_beam_files"):
399401
"src/rabbit_fifo_dlx_sup.erl",
400402
"src/rabbit_fifo_dlx_worker.erl",
401403
"src/rabbit_fifo_index.erl",
404+
"src/rabbit_fifo_q.erl",
402405
"src/rabbit_fifo_v0.erl",
403406
"src/rabbit_fifo_v1.erl",
407+
"src/rabbit_fifo_v3.erl",
404408
"src/rabbit_file.erl",
405409
"src/rabbit_global_counters.erl",
406410
"src/rabbit_guid.erl",
@@ -541,6 +545,7 @@ def all_srcs(name = "all_srcs"):
541545
"src/rabbit_fifo_dlx.hrl",
542546
"src/rabbit_fifo_v0.hrl",
543547
"src/rabbit_fifo_v1.hrl",
548+
"src/rabbit_fifo_v3.hrl",
544549
"src/rabbit_stream_coordinator.hrl",
545550
"src/rabbit_stream_sac_coordinator.hrl",
546551
],
@@ -672,8 +677,10 @@ def all_srcs(name = "all_srcs"):
672677
"src/rabbit_fifo_dlx_sup.erl",
673678
"src/rabbit_fifo_dlx_worker.erl",
674679
"src/rabbit_fifo_index.erl",
680+
"src/rabbit_fifo_q.erl",
675681
"src/rabbit_fifo_v0.erl",
676682
"src/rabbit_fifo_v1.erl",
683+
"src/rabbit_fifo_v3.erl",
677684
"src/rabbit_file.erl",
678685
"src/rabbit_global_counters.erl",
679686
"src/rabbit_guid.erl",
@@ -1288,7 +1295,8 @@ def test_suite_beam_files(name = "test_suite_beam_files"):
12881295
testonly = True,
12891296
srcs = ["test/rabbit_fifo_SUITE.erl"],
12901297
outs = ["test/rabbit_fifo_SUITE.beam"],
1291-
hdrs = ["src/rabbit_fifo.hrl"],
1298+
hdrs = ["src/rabbit_fifo.hrl",
1299+
"src/rabbit_fifo_dlx.hrl"],
12921300
app_name = "rabbit",
12931301
erlc_opts = "//:test_erlc_opts",
12941302
deps = ["//deps/rabbit_common:erlang_app"],
@@ -2142,3 +2150,13 @@ def test_suite_beam_files(name = "test_suite_beam_files"):
21422150
erlc_opts = "//:test_erlc_opts",
21432151
deps = ["//deps/amqp_client:erlang_app"],
21442152
)
2153+
erlang_bytecode(
2154+
name = "rabbit_fifo_q_SUITE_beam_files",
2155+
testonly = True,
2156+
srcs = ["test/rabbit_fifo_q_SUITE.erl"],
2157+
outs = ["test/rabbit_fifo_q_SUITE.beam"],
2158+
hdrs = ["src/rabbit_fifo.hrl"],
2159+
app_name = "rabbit",
2160+
erlc_opts = "//:test_erlc_opts",
2161+
deps = ["@proper//:erlang_app"],
2162+
)

deps/rabbit/src/mc.erl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,7 @@ record_death(Reason, SourceQueue,
383383
routing_keys = RKeys,
384384
count = 1,
385385
anns = DeathAnns},
386+
ReasonBin = atom_to_binary(Reason),
386387
Anns = case Anns0 of
387388
#{deaths := Deaths0} ->
388389
Deaths = case Deaths0 of
@@ -406,7 +407,7 @@ record_death(Reason, SourceQueue,
406407
[{Key, NewDeath} | Deaths0]
407408
end
408409
end,
409-
Anns0#{<<"x-last-death-reason">> := atom_to_binary(Reason),
410+
Anns0#{<<"x-last-death-reason">> := ReasonBin,
410411
<<"x-last-death-queue">> := SourceQueue,
411412
<<"x-last-death-exchange">> := Exchange,
412413
deaths := Deaths};
@@ -419,7 +420,6 @@ record_death(Reason, SourceQueue,
419420
_ ->
420421
[{Key, NewDeath}]
421422
end,
422-
ReasonBin = atom_to_binary(Reason),
423423
Anns0#{<<"x-first-death-reason">> => ReasonBin,
424424
<<"x-first-death-queue">> => SourceQueue,
425425
<<"x-first-death-exchange">> => Exchange,

deps/rabbit/src/mc_amqp.erl

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -222,14 +222,7 @@ get_property(priority, Msg) ->
222222
-spec protocol_state(state(), mc:annotations()) -> iolist().
223223
protocol_state(Msg0 = #msg_body_decoded{header = Header0,
224224
message_annotations = MA0}, Anns) ->
225-
FirstAcquirer = first_acquirer(Anns),
226-
Header = case Header0 of
227-
undefined ->
228-
#'v1_0.header'{durable = true,
229-
first_acquirer = FirstAcquirer};
230-
#'v1_0.header'{} ->
231-
Header0#'v1_0.header'{first_acquirer = FirstAcquirer}
232-
end,
225+
Header = update_header_from_anns(Header0, Anns),
233226
MA = protocol_state_message_annotations(MA0, Anns),
234227
Msg = Msg0#msg_body_decoded{header = Header,
235228
message_annotations = MA},
@@ -238,14 +231,7 @@ protocol_state(Msg0 = #msg_body_decoded{header = Header0,
238231
protocol_state(#msg_body_encoded{header = Header0,
239232
message_annotations = MA0,
240233
bare_and_footer = BareAndFooter}, Anns) ->
241-
FirstAcquirer = first_acquirer(Anns),
242-
Header = case Header0 of
243-
undefined ->
244-
#'v1_0.header'{durable = true,
245-
first_acquirer = FirstAcquirer};
246-
#'v1_0.header'{} ->
247-
Header0#'v1_0.header'{first_acquirer = FirstAcquirer}
248-
end,
234+
Header = update_header_from_anns(Header0, Anns),
249235
MA = protocol_state_message_annotations(MA0, Anns),
250236
Sections = to_sections(Header, MA, []),
251237
[encode(Sections), BareAndFooter];
@@ -269,10 +255,9 @@ protocol_state(#v1{message_annotations = MA0,
269255
_ ->
270256
undefined
271257
end,
272-
Header = #'v1_0.header'{durable = Durable,
273-
priority = Priority,
274-
ttl = Ttl,
275-
first_acquirer = first_acquirer(Anns)},
258+
Header = update_header_from_anns(#'v1_0.header'{durable = Durable,
259+
priority = Priority,
260+
ttl = Ttl}, Anns),
276261
MA = protocol_state_message_annotations(MA0, Anns),
277262
Sections = to_sections(Header, MA, []),
278263
[encode(Sections), BareAndFooter].
@@ -573,13 +558,22 @@ msg_body_encoded([{{pos, Pos}, {body, Code}}], BarePos, Msg)
573558
binary_part_bare_and_footer(Payload, Start) ->
574559
binary_part(Payload, Start, byte_size(Payload) - Start).
575560

576-
-spec first_acquirer(mc:annotations()) -> boolean().
577-
first_acquirer(Anns) ->
561+
update_header_from_anns(undefined, Anns) ->
562+
update_header_from_anns(#'v1_0.header'{durable = true}, Anns);
563+
update_header_from_anns(Header, Anns) ->
564+
DeliveryCount = case Anns of
565+
#{delivery_count := C} -> C;
566+
_ -> 0
567+
end,
578568
Redelivered = case Anns of
579569
#{redelivered := R} -> R;
580570
_ -> false
581571
end,
582-
not Redelivered.
572+
FirstAcq = not Redelivered andalso
573+
DeliveryCount =:= 0 andalso
574+
not is_map_key(deaths, Anns),
575+
Header#'v1_0.header'{first_acquirer = FirstAcq,
576+
delivery_count = {uint, DeliveryCount}}.
583577

584578
encode_deaths(Deaths) ->
585579
lists:map(

deps/rabbit/src/mc_amqpl.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ convert_from(mc_amqp, Sections, Env) ->
176176
{Headers2, CorrId091} = message_id(CorrId, <<"x-correlation-id">>, Headers1),
177177

178178
Headers = case Env of
179-
#{message_containers_store_amqp_v1 := false} ->
179+
#{'rabbitmq_4.0.0' := false} ->
180180
Headers3 = case AProp of
181181
undefined ->
182182
Headers2;

deps/rabbit/src/mc_compat.erl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ get_annotation(?ANN_ROUTING_KEYS, #basic_message{routing_keys = RKeys}) ->
5454
get_annotation(?ANN_EXCHANGE, #basic_message{exchange_name = Ex}) ->
5555
Ex#resource.name;
5656
get_annotation(id, #basic_message{id = Id}) ->
57-
Id.
57+
Id;
58+
get_annotation(_Key, #basic_message{}) ->
59+
undefined.
5860

5961
set_annotation(id, Value, #basic_message{} = Msg) ->
6062
Msg#basic_message{id = Value};

deps/rabbit/src/rabbit_amqp_session.erl

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@
187187
send_settled :: boolean(),
188188
max_message_size :: unlimited | pos_integer(),
189189

190-
%% When feature flag credit_api_v2 becomes required,
190+
%% When feature flag rabbitmq_4.0.0 becomes required,
191191
%% the following 2 fields should be deleted.
192192
credit_api_version :: 1 | 2,
193193
%% When credit API v1 is used, our session process holds the delivery-count
@@ -225,7 +225,7 @@
225225
frames :: [transfer_frame_body(), ...],
226226
queue_ack_required :: boolean(),
227227
%% Queue that sent us this message.
228-
%% When feature flag credit_api_v2 becomes required, this field should be deleted.
228+
%% When feature flag rabbitmq_4.0.0 becomes required, this field should be deleted.
229229
queue_pid :: pid() | credit_api_v2,
230230
delivery_id :: delivery_number(),
231231
outgoing_unsettled :: #outgoing_unsettled{}
@@ -1068,17 +1068,17 @@ handle_control(#'v1_0.attach'{role = ?AMQP_ROLE_RECEIVER,
10681068
QType = amqqueue:get_type(Q),
10691069
%% Whether credit API v1 or v2 is used is decided only here at link attachment time.
10701070
%% This decision applies to the whole life time of the link.
1071-
%% This means even when feature flag credit_api_v2 will be enabled later, this consumer will
1071+
%% This means even when feature flag rabbitmq_4.0.0 will be enabled later, this consumer will
10721072
%% continue to use credit API v1. This is the safest and easiest solution avoiding
10731073
%% transferring link flow control state (the delivery-count) at runtime from this session
10741074
%% process to the queue process.
1075-
%% Eventually, after feature flag credit_api_v2 gets enabled and a subsequent rolling upgrade,
1075+
%% Eventually, after feature flag rabbitmq_4.0.0 gets enabled and a subsequent rolling upgrade,
10761076
%% all consumers will use credit API v2.
10771077
%% Streams always use credit API v2 since the stream client (rabbit_stream_queue) holds the link
10781078
%% flow control state. Hence, credit API mixed version isn't an issue for streams.
10791079
{CreditApiVsn, Mode, DeliveryCount, ClientFlowCtl,
10801080
QueueFlowCtl, CreditReqInFlight, StashedCreditReq} =
1081-
case rabbit_feature_flags:is_enabled(credit_api_v2) orelse
1081+
case rabbit_feature_flags:is_enabled('rabbitmq_4.0.0') orelse
10821082
QType =:= rabbit_stream_queue of
10831083
true ->
10841084
{2,
@@ -1861,20 +1861,30 @@ settle_op_from_outcome(#'v1_0.rejected'{}) ->
18611861
discard;
18621862
settle_op_from_outcome(#'v1_0.released'{}) ->
18631863
requeue;
1864-
%% Keep the same Modified behaviour as in RabbitMQ 3.x
1865-
settle_op_from_outcome(#'v1_0.modified'{delivery_failed = true,
1866-
undeliverable_here = UndelHere})
1867-
when UndelHere =/= true ->
1868-
requeue;
1869-
settle_op_from_outcome(#'v1_0.modified'{}) ->
1870-
%% If delivery_failed is not true, we can't increment its delivery_count.
1871-
%% So, we will have to reject without requeue.
1872-
%%
1873-
%% If undeliverable_here is true, this is not quite correct because
1874-
%% undeliverable_here refers to the link, and not the message in general.
1875-
%% However, we cannot filter messages from being assigned to individual consumers.
1876-
%% That's why we will have to reject it without requeue.
1877-
discard;
1864+
1865+
%% Not all queue types support the modified outcome fields correctly.
1866+
%% However, we still allow the client to settle with the modified outcome
1867+
%% because some client libraries such as Apache QPid make use of it:
1868+
%% https://github.com/apache/qpid-jms/blob/90eb60f59cb59b7b9ad8363ee8a843d6903b8e77/qpid-jms-client/src/main/java/org/apache/qpid/jms/JmsMessageConsumer.java#L464
1869+
%% In such cases, it's better when RabbitMQ does not end the session.
1870+
%% See https://github.com/rabbitmq/rabbitmq-server/issues/6121
1871+
settle_op_from_outcome(#'v1_0.modified'{delivery_failed = DelFailed,
1872+
undeliverable_here = UndelHere,
1873+
message_annotations = Anns0
1874+
}) ->
1875+
Anns = case Anns0 of
1876+
#'v1_0.message_annotations'{content = C} ->
1877+
C;
1878+
_ ->
1879+
[]
1880+
end,
1881+
{modify,
1882+
default(DelFailed, false),
1883+
default(UndelHere, false),
1884+
%% TODO: this must exist elsewhere
1885+
lists:foldl(fun ({{symbol, K}, V}, Acc) ->
1886+
Acc#{K => unwrap(V)}
1887+
end, #{}, Anns)};
18781888
settle_op_from_outcome(Outcome) ->
18791889
protocol_error(
18801890
?V_1_0_AMQP_ERROR_INVALID_FIELD,
@@ -1981,7 +1991,7 @@ handle_queue_actions(Actions, State) ->
19811991
S0 = #state{outgoing_links = OutgoingLinks0,
19821992
outgoing_pending = Pending}) ->
19831993
%% credit API v1
1984-
%% Delete this branch when feature flag credit_api_v2 becomes required.
1994+
%% Delete this branch when feature flag rabbitmq_4.0.0 becomes required.
19851995
Handle = ctag_to_handle(Ctag),
19861996
Link = #outgoing_link{delivery_count = Count0} = maps:get(Handle, OutgoingLinks0),
19871997
{Count, Credit, S} = case Drain of
@@ -2788,7 +2798,7 @@ delivery_count_rcv(undefined) ->
27882798
%% credits to a queue has to synchronously wait for a credit reply from the queue:
27892799
%% https://github.com/rabbitmq/rabbitmq-server/blob/b9566f4d02f7ceddd2f267a92d46affd30fb16c8/deps/rabbitmq_codegen/credit_extension.json#L43
27902800
%% This blocks our entire AMQP 1.0 session process. Since the credit reply from the
2791-
%% queue did not contain the consumr tag prior to feature flag credit_api_v2, we
2801+
%% queue did not contain the consumr tag prior to feature flag rabbitmq_4.0.0, we
27922802
%% must behave here the same way as non-native AMQP 1.0: We wait until the queue
27932803
%% sends us a credit reply sucht that we can correlate that reply with our consumer tag.
27942804
process_credit_reply_sync(
@@ -2853,7 +2863,7 @@ process_credit_reply_sync_quorum_queue(Ctag, QName, Credit, State0) ->
28532863
no_return().
28542864
credit_reply_timeout(QType, QName) ->
28552865
Fmt = "Timed out waiting for credit reply from ~s ~s. "
2856-
"Hint: Enable feature flag credit_api_v2",
2866+
"Hint: Enable feature flag rabbitmq_4.0.0",
28572867
Args = [QType, rabbit_misc:rs(QName)],
28582868
rabbit_log:error(Fmt, Args),
28592869
protocol_error(?V_1_0_AMQP_ERROR_INTERNAL_ERROR, Fmt, Args).
@@ -3441,12 +3451,13 @@ cap_credit(DesiredCredit) ->
34413451
min(DesiredCredit, MaxCredit).
34423452

34433453
ensure_mc_cluster_compat(Mc) ->
3444-
IsEnabled = rabbit_feature_flags:is_enabled(message_containers_store_amqp_v1),
3454+
Feature = 'rabbitmq_4.0.0',
3455+
IsEnabled = rabbit_feature_flags:is_enabled(Feature),
34453456
case IsEnabled of
34463457
true ->
34473458
Mc;
34483459
false ->
3449-
McEnv = #{message_containers_store_amqp_v1 => IsEnabled},
3460+
McEnv = #{Feature => IsEnabled},
34503461
%% other nodes in the cluster may not understand the new internal
34513462
%% amqp mc format - in this case we convert to AMQP legacy format
34523463
%% for compatibility
@@ -3497,3 +3508,8 @@ format_status(
34973508
permission_cache => PermissionCache,
34983509
topic_permission_cache => TopicPermissionCache},
34993510
maps:update(state, State, Status).
3511+
3512+
unwrap({_Tag, V}) ->
3513+
V;
3514+
unwrap(V) ->
3515+
V.

deps/rabbit/src/rabbit_amqp_writer.erl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ send_command_sync(Writer, ChannelNum, Performative) ->
7474
Request = {send_command, ChannelNum, Performative},
7575
gen_server:call(Writer, Request, ?CALL_TIMEOUT).
7676

77-
%% Delete this function when feature flag credit_api_v2 becomes required.
77+
%% Delete this function when feature flag rabbitmq_4.0.0 becomes required.
7878
-spec send_command_and_notify(pid(),
7979
pid(),
8080
rabbit_types:channel_number(),
@@ -111,7 +111,7 @@ handle_cast({send_command, SessionPid, ChannelNum, Performative, Payload}, State
111111
State1 = internal_send_command_async(ChannelNum, Performative, Payload, State0),
112112
State = credit_flow_ack(SessionPid, State1),
113113
no_reply(State);
114-
%% Delete below function clause when feature flag credit_api_v2 becomes required.
114+
%% Delete below function clause when feature flag rabbitmq_4.0.0 becomes required.
115115
handle_cast({send_command_and_notify, QueuePid, SessionPid, ChannelNum, Performative, Payload}, State0) ->
116116
State1 = internal_send_command_async(ChannelNum, Performative, Payload, State0),
117117
State = credit_flow_ack(SessionPid, State1),
@@ -131,7 +131,7 @@ handle_info({{'DOWN', session}, _MRef, process, SessionPid, _Reason},
131131
credit_flow:peer_down(SessionPid),
132132
State = State0#state{monitored_sessions = maps:remove(SessionPid, Sessions)},
133133
no_reply(State);
134-
%% Delete below function clause when feature flag credit_api_v2 becomes required.
134+
%% Delete below function clause when feature flag rabbitmq_4.0.0 becomes required.
135135
handle_info({'DOWN', _MRef, process, QueuePid, _Reason}, State) ->
136136
rabbit_amqqueue:notify_sent_queue_down(QueuePid),
137137
no_reply(State).

deps/rabbit/src/rabbit_amqqueue_process.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1516,7 +1516,7 @@ handle_cast({credit, SessionPid, CTag, Credit, Drain},
15161516
backing_queue = BQ,
15171517
backing_queue_state = BQS0} = State) ->
15181518
%% Credit API v1.
1519-
%% Delete this function clause when feature flag credit_api_v2 becomes required.
1519+
%% Delete this function clause when feature flag rabbitmq_4.0.0 becomes required.
15201520
%% Behave like non-native AMQP 1.0: Send send_credit_reply before deliveries.
15211521
rabbit_classic_queue:send_credit_reply_credit_api_v1(
15221522
SessionPid, amqqueue:get_name(Q), BQ:len(BQS0)),

0 commit comments

Comments
 (0)