|
187 | 187 | send_settled :: boolean(),
|
188 | 188 | max_message_size :: unlimited | pos_integer(),
|
189 | 189 |
|
190 |
| - %% When feature flag credit_api_v2 becomes required, |
| 190 | + %% When feature flag rabbitmq_4.0.0 becomes required, |
191 | 191 | %% the following 2 fields should be deleted.
|
192 | 192 | credit_api_version :: 1 | 2,
|
193 | 193 | %% When credit API v1 is used, our session process holds the delivery-count
|
|
225 | 225 | frames :: [transfer_frame_body(), ...],
|
226 | 226 | queue_ack_required :: boolean(),
|
227 | 227 | %% 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. |
229 | 229 | queue_pid :: pid() | credit_api_v2,
|
230 | 230 | delivery_id :: delivery_number(),
|
231 | 231 | outgoing_unsettled :: #outgoing_unsettled{}
|
@@ -1068,17 +1068,17 @@ handle_control(#'v1_0.attach'{role = ?AMQP_ROLE_RECEIVER,
|
1068 | 1068 | QType = amqqueue:get_type(Q),
|
1069 | 1069 | %% Whether credit API v1 or v2 is used is decided only here at link attachment time.
|
1070 | 1070 | %% 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 |
1072 | 1072 | %% continue to use credit API v1. This is the safest and easiest solution avoiding
|
1073 | 1073 | %% transferring link flow control state (the delivery-count) at runtime from this session
|
1074 | 1074 | %% 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, |
1076 | 1076 | %% all consumers will use credit API v2.
|
1077 | 1077 | %% Streams always use credit API v2 since the stream client (rabbit_stream_queue) holds the link
|
1078 | 1078 | %% flow control state. Hence, credit API mixed version isn't an issue for streams.
|
1079 | 1079 | {CreditApiVsn, Mode, DeliveryCount, ClientFlowCtl,
|
1080 | 1080 | 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 |
1082 | 1082 | QType =:= rabbit_stream_queue of
|
1083 | 1083 | true ->
|
1084 | 1084 | {2,
|
@@ -1861,20 +1861,30 @@ settle_op_from_outcome(#'v1_0.rejected'{}) ->
|
1861 | 1861 | discard;
|
1862 | 1862 | settle_op_from_outcome(#'v1_0.released'{}) ->
|
1863 | 1863 | 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)}; |
1878 | 1888 | settle_op_from_outcome(Outcome) ->
|
1879 | 1889 | protocol_error(
|
1880 | 1890 | ?V_1_0_AMQP_ERROR_INVALID_FIELD,
|
@@ -1981,7 +1991,7 @@ handle_queue_actions(Actions, State) ->
|
1981 | 1991 | S0 = #state{outgoing_links = OutgoingLinks0,
|
1982 | 1992 | outgoing_pending = Pending}) ->
|
1983 | 1993 | %% 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. |
1985 | 1995 | Handle = ctag_to_handle(Ctag),
|
1986 | 1996 | Link = #outgoing_link{delivery_count = Count0} = maps:get(Handle, OutgoingLinks0),
|
1987 | 1997 | {Count, Credit, S} = case Drain of
|
@@ -2788,7 +2798,7 @@ delivery_count_rcv(undefined) ->
|
2788 | 2798 | %% credits to a queue has to synchronously wait for a credit reply from the queue:
|
2789 | 2799 | %% https://github.com/rabbitmq/rabbitmq-server/blob/b9566f4d02f7ceddd2f267a92d46affd30fb16c8/deps/rabbitmq_codegen/credit_extension.json#L43
|
2790 | 2800 | %% 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 |
2792 | 2802 | %% must behave here the same way as non-native AMQP 1.0: We wait until the queue
|
2793 | 2803 | %% sends us a credit reply sucht that we can correlate that reply with our consumer tag.
|
2794 | 2804 | process_credit_reply_sync(
|
@@ -2853,7 +2863,7 @@ process_credit_reply_sync_quorum_queue(Ctag, QName, Credit, State0) ->
|
2853 | 2863 | no_return().
|
2854 | 2864 | credit_reply_timeout(QType, QName) ->
|
2855 | 2865 | 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", |
2857 | 2867 | Args = [QType, rabbit_misc:rs(QName)],
|
2858 | 2868 | rabbit_log:error(Fmt, Args),
|
2859 | 2869 | protocol_error(?V_1_0_AMQP_ERROR_INTERNAL_ERROR, Fmt, Args).
|
@@ -3441,12 +3451,13 @@ cap_credit(DesiredCredit) ->
|
3441 | 3451 | min(DesiredCredit, MaxCredit).
|
3442 | 3452 |
|
3443 | 3453 | 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), |
3445 | 3456 | case IsEnabled of
|
3446 | 3457 | true ->
|
3447 | 3458 | Mc;
|
3448 | 3459 | false ->
|
3449 |
| - McEnv = #{message_containers_store_amqp_v1 => IsEnabled}, |
| 3460 | + McEnv = #{Feature => IsEnabled}, |
3450 | 3461 | %% other nodes in the cluster may not understand the new internal
|
3451 | 3462 | %% amqp mc format - in this case we convert to AMQP legacy format
|
3452 | 3463 | %% for compatibility
|
@@ -3497,3 +3508,8 @@ format_status(
|
3497 | 3508 | permission_cache => PermissionCache,
|
3498 | 3509 | topic_permission_cache => TopicPermissionCache},
|
3499 | 3510 | maps:update(state, State, Status).
|
| 3511 | + |
| 3512 | +unwrap({_Tag, V}) -> |
| 3513 | + V; |
| 3514 | +unwrap(V) -> |
| 3515 | + V. |
0 commit comments