Quorum queues were introduced in RabbitMQ 3.8.0. This was first time we
added a breaking change protected behind a feature flag. This allowed a
RabbitMQ cluster to be upgraded one node at a time, without having to
stop the entire cluster.
The breaking change was a new field in the `#amqqueue{}` record. This
broke the API and the ABI because records are a compile-time thing in
Erlang.
The compatibility code is in the wild for long enough that we want to
support the new `#amqqueue{}` record only from now on. The
`quorum_queue` feature flag was marked as required in a previous commit
(see #5202). This allows us to remove code in this patch.
References #5215.
This feature flag was introduced because a new field was added to the
`#vhost{}` record. This was a breaking change the feature flag allowed a
RabbitMQ cluster to be upgraded one node at a time, without having to
stop the entire cluster.
The compatibility code is in the wild for long enough that we want to
support the new `#vhost{}` record only from now on. The
`virtual_host_metadata` feature flag was marked as required in a
previous commit (see #5202). This allows us to remove code in this
patch.
References #5215.
Implicit default bindings, introduced in RabbitMQ 3.8.x, was a breaking change
protected behind a feature flag. This allowed a RabbitMQ cluster to be
upgraded one node at a time, without having to stop the entire cluster.
The compatibility code is in the wild for long enough. The
`implicit_default_bindings` feature flag was marked as required in a
previous commit (see #5202). This allows us to remove code in this
patch.
References #5215.
Since the migration function for feature flag direct_exchange_routing_v2
does dirty reads on table rabbit_exchange, let's set a read lock on
that whole table.
In theory, it's not really necessary since bindings are modified within
transactions contexts.
However, let's be safe and set that read lock.
Function rabbit_binding:populate_index_route_table/0
takes less than a few seconds with many thousands of bindings.
So, it shouldn't harm that no exchanges can be created / deleted in that
short time period when enabling the feature flag.
Also, abort the transaction and return an error in the feature flag
migration is a source exchange cannot be found.
This is the safest thing to do because we do not want any routes to be
missing in rabbit_index_route table.
This branch should never hit.
However, if a source exchange is not present anymore,
delete its bindings from rabbit_index_route.
If the binding doesn't exist is rabbit_index_route, the delete operation
is a no-op.
Before this change `rabbit_channel_tracking` used node+name as primary
key of the channel tracking table. As the `channel_closed` event might
only contain the channel pid and not node and name,
`rabbit_channel_tracking` used a full-table-scan matching in
`get_tracked_channel_by_pid/1` to look up and unregister the closed
channel. Now that channel pid is the key unregistering channels should
be constant time and not proportional to the number of tracked channels.
Maintenance mode, introduced in RabbitMQ 3.8.x, was a breaking change
protected behind a feature flag. This allowed a RabbitMQ cluster to be
upgraded one node at a time, without having to stop the entire cluster.
The compatibility code is in the wild for long enough. The
`maintenance_mode_status` feature flag was marked as required in a
previous commit (see #5202). This allows us to remove code in this
patch.
References #5215.
User limits required a breaking change protected behind a feature flag.
This allowed a RabbitMQ cluster to be upgraded one node at a time,
without having to stop the entire cluster.
The breaking change was a new field in the `#internal_user{}` record. This
broke the API and the ABI because records are a compile-time thing in
Erlang.
The compatibility code is in the wild for long enough that we want to
support the new `#internal_user{}` record only from now on. The
`user_limits` feature flag was marked as required in a previous commit
(see #5202). This allows us to remove code in this patch.
References #5215.
Back in 2016, JSON encoding and
much of the Erlang ecosystem used
proplists, which can lead to duplicate
keys in JSON documents.
In 2022 some JSON libraries only
decode JSON to maps, and maps
have unique keys, so these tests
are not worth adjusting or reproducing
with maps.
Per discussion with the team.
Thoas is more efficient both in terms of encoding
time and peak memory footprint.
In the process we have discovered an issue:
https://github.com/lpil/thoas/issues/15
Pair: @pjk25
`rabbit_ff_registry` is an internal module of the feature flags
subsystem, it is not meant to be called outside of it. In particular, it
may lead to crashes very difficult to debug when a feature flag is
enabled. The reason is that this module is compiled and reloaded at
runtime, so the module may disappear for a small period of time. Another
reason is that a process calling `rabbit_ff_registry` may hold that
module, preventing the feature flags subsystem from performing its task.
The correct public API to query the state of a feature flag is
`rabbit_feature_flags:is_enabled/1`. It will always return a boolean. If
the feature flag being queried is in `state_changing` state, this
function takes care of waiting for the outcome.
See #5018.