Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Shovel: use message containers #14096

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

Shovel: use message containers #14096

wants to merge 2 commits into from

Conversation

dcorbacho
Copy link
Contributor

See #13957

@dcorbacho dcorbacho marked this pull request as ready for review June 19, 2025 12:11
@dcorbacho
Copy link
Contributor Author

dcorbacho commented Jun 19, 2025

I think the only breaking change is the translation of type from amqp0.9.1 into the message annotationx-basic-type in amqp1.0, as translated by our message container implementation. Previously it was translated to type in the application properties, which is probably a bug. See https://www.rabbitmq.com/docs/conversions#amqpl-amqp

Copy link
Member

@ansd ansd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a message is shovelled from RabbitMQ to another AMQP 1.0 broker, I would expect the following to happen:

RabbitMQ encodes and sends the message.

This can be achieved by using the rabbit_queue_type API directly, as suggested by @kjnilsson initially and as described in #13957 (comment): The shovel plugin would consume directly from the queue, encode and then send the message.

If I read the code correctly, the following happens with this PR:

RabbitMQ encodes the message -> sends the message to shovel plugin -> shovel plugin decodes the message in the AMQP 1.0 client -> shovel plugin encodes the message to create a message container -> mc_amqp on the shovel plugin then decodes the message -> in rabbit_amqp10_shovel.erl:forward/3 the shovel plugin then encodes the message -> the shovel plugin then decodes the message for a format suitable by the AMQP 1.0 client, the AMQP 1.0 client then encodes the message before finally sending it.

Therefore, with this PR there are 7 (!) different encode/decode steps instead of the final goal to have only 1 step (and instead of 3 steps prior to this PR).

So, while this PR uses message containers for conversions and therefore solves one problem, it seems that performance gets worse compared to prior to this PR.

Have you done any performance tests?

That said, it's up to you to decide whether we want to accept a potentially severe performance drop as an interim solution until using rabbit_queue_type API.

@dcorbacho
Copy link
Contributor Author

@ansd How we are going to use the rabbit_queue_type API directly and skip the client? Unless I'm missing something, for the queue type to be used the shovel should be in the same cluster.

Comment on lines 273 to 289
case is_amqp10_body(Body) orelse (not is_list(Body)) of
true ->
#amqp10_msg{
transfer = #'v1_0.transfer'{
delivery_tag = {binary, DeliveryTag},
settled = Settled,
message_format = {uint, ?MESSAGE_FORMAT}},
%% This lib is safe by default.
header = #'v1_0.header'{durable = true},
body = Body};
false ->
Transfer = #'v1_0.transfer'{
delivery_tag = {binary, DeliveryTag},
settled = Settled,
message_format = {uint, ?MESSAGE_FORMAT}},
from_amqp_records([Transfer | Body])
end.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function spec is now wrong: The function spec expects currently a body, but not other sections.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The creation of the 'v1_0.transfer' record got duplicated. Avoid code duplication.

@ansd
Copy link
Member

ansd commented Jun 19, 2025

How we are going to use the rabbit_queue_type API directly and skip the client? Unless I'm missing something, for the queue type to be used the shovel should be in the same cluster.

Correct, the assumption of using rabbit_queue_type API directly is that either the shovel source or destination is located in the cluster where the shovel runs. This is the common case. Shovels usually forward broker local messages to a remote broker, or the other way around from a remote broker to the local broker. In both cases, using rabbit_queue_type API directly will greatly speed up performance.

The case where rabbit_queue_type cannot be used at all is if the shovel runs on neither the source nor the destination, but on some 3rd broker. This is a rather uncommon setup.

@kjnilsson
Copy link
Contributor

Correct, the assumption of using rabbit_queue_type API directly is that either the shovel source or destination is located in the cluster where the shovel runs. This is the common case. Shovels usually forward broker local messages to a remote broker, or the other way around from a remote broker to the local broker. In both cases, using rabbit_queue_type API directly will greatly speed up performance.

I think that would need to be a new "internal" shovel protocol impl which may be slightly beyond the scope of this PR. But I agree that is where we want to be.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants