Skip to content
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

Add support for ulong header values #1299

Closed

Conversation

thepunkoff
Copy link

@thepunkoff thepunkoff commented Feb 14, 2023

Proposed Changes

I added support for having ulongs as header table values for convenience, since uints and ushorts support has already been added.

Types of Changes

  • Bug fix (non-breaking change which fixes issue #NNNN)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause an observable behavior change in existing systems)
  • Documentation improvements (corrections, new content, etc)
  • Cosmetic change (whitespace, formatting, etc)

Checklist

  • I have read the CONTRIBUTING.md document
  • I have signed the CA (see https://cla.pivotal.io/sign/rabbitmq)
  • All tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if appropriate)
  • Any dependent changes have been merged and published in related repositories

Further Comments


@pivotal-cla
Copy link

@thepunkoff Please sign the Contributor License Agreement!

Click here to manually synchronize the status of this Pull Request.

See the FAQ for frequently asked questions.

@pivotal-cla
Copy link

@thepunkoff Thank you for signing the Contributor License Agreement!

@thepunkoff
Copy link
Author

thepunkoff commented Feb 14, 2023

The CI build failed, but I can't see the reasons why. It just says "loading" forever.

@lukebakken lukebakken self-assigned this Feb 14, 2023
@lukebakken lukebakken added this to the 6.5.0 milestone Feb 14, 2023
Copy link
Contributor

@lukebakken lukebakken left a comment

Choose a reason for hiding this comment

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

Thanks!

Build failure:

/tmp/build/b95f7b06/rabbitmq_dotnet_client/projects/Unit/TestFieldTableFormatting.cs(80,33): error CS1003: Syntax error, ',' expected [/tmp/build/b95f7b06/rabbitmq_dotnet_client/projects/Unit/Unit.csproj]
/tmp/build/b95f7b06/rabbitmq_dotnet_client/projects/Unit/TestFieldTableFormattingGeneric.cs(82,33): error CS1003: Syntax error, ',' expected [/tmp/build/b95f7b06/rabbitmq_dotnet_client/projects/Unit/Unit.csproj]
  Benchmarks -> /tmp/build/b95f7b06/rabbitmq_dotnet_client/projects/Benchmarks/bin/Debug/net472/Benchmarks.exe
/tmp/build/b95f7b06/rabbitmq_dotnet_client/projects/Unit/TestFieldTableFormatting.cs(80,33): error CS1003: Syntax error, ',' expected [/tmp/build/b95f7b06/rabbitmq_dotnet_client/projects/Unit/Unit.csproj]
/tmp/build/b95f7b06/rabbitmq_dotnet_client/projects/Unit/TestFieldTableFormattingGeneric.cs(82,33): error CS1003: Syntax error, ',' expected [/tmp/build/b95f7b06/rabbitmq_dotnet_client/projects/Unit/Unit.csproj]

Build FAILED.

I would fix this for you but I'm caught up in customer support!

@thepunkoff
Copy link
Author

@lukebakken Thanks for helping! I fixed the build.

Copy link
Contributor

@Zerpet Zerpet left a comment

Choose a reason for hiding this comment

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

Actions failed on formatting. Apart from that, this looks good to me. Thank you for your contribution!

@thepunkoff
Copy link
Author

thepunkoff commented Feb 15, 2023

There's now a flaky test failure, that prevents this from being merged, but I'm not sure how to rerun the check.

@michaelklishin
Copy link
Member

There is one test that fails only on Windows, and the client seemingly goes into a (reconnection) loop that never succeeds:

Testing heartbeats, sleeping for 60 seconds
  Passed RabbitMQ.Client.Unit.TestFloodPublishing.TestMultithreadFloodPublishing [170 ms]
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   at System.IO.BufferedStream.Read(Byte[] array, Int32 offset, Int32 count)
   at RabbitMQ.Client.Impl.InboundFrame.ReadFromStream(Stream reader, Byte[] buffer, Int32 toRead) in D:\a\rabbitmq-dotnet-client\rabbitmq-dotnet-client\projects\RabbitMQ.Client\client\impl\Frame.cs:line 318
   at RabbitMQ.Client.Impl.InboundFrame.ReadFrom(Stream reader, Byte[] frameHeaderBuffer, UInt32 maxMessageSize) in D:\a\rabbitmq-dotnet-client\rabbitmq-dotnet-client\projects\RabbitMQ.Client\client\impl\Frame.cs:line 268
   at RabbitMQ.Client.Impl.SocketFrameHandler.ReadFrame() in D:\a\rabbitmq-dotnet-client\rabbitmq-dotnet-client\projects\RabbitMQ.Client\client\impl\SocketFrameHandler.cs:line 243
   at RabbitMQ.Client.Framing.Impl.Connection.ReceiveLoop() in D:\a\rabbitmq-dotnet-client\rabbitmq-dotnet-client\projects\RabbitMQ.Client\client\impl\Connection.Receive.cs:line 73
   at RabbitMQ.Client.Framing.Impl.Connection.MainLoop() in D:\a\rabbitmq-dotnet-client\rabbitmq-dotnet-client\projects\RabbitMQ.Client\client\impl\Connection.Receive.cs:line 50
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   at System.IO.BufferedStream.Read(Byte[] array, Int32 offset, Int32 count)
   at RabbitMQ.Client.Impl.InboundFrame.ReadFromStream(Stream reader, Byte[] buffer, Int32 toRead) in D:\a\rabbitmq-dotnet-client\rabbitmq-dotnet-client\projects\RabbitMQ.Client\client\impl\Frame.cs:line 318
   at RabbitMQ.Client.Impl.InboundFrame.ReadFrom(Stream reader, Byte[] frameHeaderBuffer, UInt32 maxMessageSize) in D:\a\rabbitmq-dotnet-client\rabbitmq-dotnet-client\projects\RabbitMQ.Client\client\impl\Frame.cs:line 268
   at RabbitMQ.Client.Impl.SocketFrameHandler.ReadFrame() in D:\a\rabbitmq-dotnet-client\rabbitmq-dotnet-client\projects\RabbitMQ.Client\client\impl\SocketFrameHandler.cs:line 243
   at RabbitMQ.Client.Framing.Impl.Connection.ReceiveLoop() in D:\a\rabbitmq-dotnet-client\rabbitmq-dotnet-client\projects\RabbitMQ.Client\client\impl\Connection.Receive.cs:line 73
   at RabbitMQ.Client.Framing.Impl.Connection.MainLoop() in D:\a\rabbitmq-dotnet-client\rabbitmq-dotnet-client\projects\RabbitMQ.Client\client\impl\Connection.Receive.cs:line 50
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)

Anyhow, it does not seem to be related to this PR in any way. The same test passes on Linux.

michaelklishin
michaelklishin previously approved these changes Feb 15, 2023
@Zerpet Zerpet linked an issue Feb 15, 2023 that may be closed by this pull request
Copy link
Contributor

@lukebakken lukebakken left a comment

Choose a reason for hiding this comment

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

We should at least be compatible with Pika:

https://github.com/pika/pika/blob/main/pika/data.py#L256-L259

PS @thepunkoff thanks for your contribution. If you wouldn't mind making sure this change uses the same single-character as Pika, that would be great.

@thepunkoff
Copy link
Author

@lukebakken Ok! I can see that pika uses l for unsigned 64-bit ints and L for signed 64-bit ints. On the other hand the dotnet client lib has been using l for signed ones instead - I'll swap them then to match pika's.

@michaelklishin
Copy link
Member

@lukebakken @thepunkoff I don't mind using the same value as Pika but keep this protocol errata in mind. I'd say we should use what the Java client uses and not Pika (in case there is a difference).

@thepunkoff
Copy link
Author

thepunkoff commented Feb 15, 2023

@michaelklishin Oh I see now... my bad! So my PR would remove disambiguity between 0-9-1 and RabbitMQ considering longs and ulongs.

However, the Java client currently doesn't support ulongs either. Should I update it as well?

@thepunkoff thepunkoff force-pushed the support-ulong-in-header-values branch from 121b851 to 9d2a5e0 Compare February 15, 2023 18:33
@thepunkoff
Copy link
Author

Oops, sorry for messing up commits 😅

@michaelklishin
Copy link
Member

@thepunkoff we would appreciate support for the same type in the Java client, of course. To me it appears that Pika uses l as in the original AMQP 0-9-1 spec and not what RabbitMQ and Qpid have adopted.

So both this client and the Java one should the same value, what the RabbitMQ server uses.

@thepunkoff
Copy link
Author

Just to clarify. Does the RabbitMQ server use header values as opposed to just passing them along to the consumer to be interpreted by the application? If the server expects values in an exact format, then is it even ok to change anything on the client libraries' side? Should the server be patched to support this, too? How would the server react to such rearrangements in clients?

Considering the errata document. It is stated that there are incompatibilities between amqp 0-9-1 and rmq, I can see those. So does this mean that amqp 0-9-1 clients are not compatible with rmq, and rmq clients are not compatible with 0-9-1-compliant servers? How should I interpret this document? As a todo list or as a rule to follow? Not quite sure yet. Would be glad if y'all clarified it to me :)

@lukebakken
Copy link
Contributor

lukebakken commented Feb 15, 2023

@thepunkoff
Copy link
Author

thepunkoff commented Feb 16, 2023

@lukebakken Here's a quote from the errata doc:

RabbitMQ continues to use the tags in the third column.

This actually says the type characters are used. If they're not, and the information is obsolete, then great.

Do you think the field type specifiers in this client should fully conform to the 0-9-1 spec (p. 31-32)? I could make sure they do in this PR, and then update the Java client accordingly. But this should be subsequently done in all the known client libraries.

Also, if an updated client uses new type specifiers, the non-updated clients will be mislead, as e.g. long values in the headers from the updated client would start to use 'L' instead of 'l'.

@Zerpet
Copy link
Contributor

Zerpet commented Feb 16, 2023

@thepunkoff we would appreciate support for the same type in the Java client, of course. To me it appears that Pika uses l as in the original AMQP 0-9-1 spec and not what RabbitMQ and Qpid have adopted.

So both this client and the Java one should the same value, what the RabbitMQ server uses.

I agree, we should adapt the clients to use what RabbitMQ server uses. At the end of the day, these clients are rabbitmq clients, not pure AMQP 0.9.1 clients.

The Go client seems to follow the same criteria as Java and Pika:

https://github.com/rabbitmq/amqp091-go/blob/5656876376f5139fc349ea903eede73682eff738/read.go#L142-L254

@michaelklishin
Copy link
Member

We definitely won't update all clients to use the ambiguous values from the original spec (that were never clarified).

@lukebakken
Copy link
Contributor

lukebakken commented Feb 16, 2023

Here's where L and l are used in RabbitMQ:
https://github.com/rabbitmq/rabbitmq-server/blob/main/deps/rabbit_common/src/rabbit_binary_parser.erl#L62-L67

I was confusing message headers with the actual framing of messages 🤕

@michaelklishin
Copy link
Member

So rabbitmq/rabbitmq-server#1093 (comment) from 2017 suggests we have decided to not support unsigned longs but to support signed longs as effectively all programming languages have a way of representing them on 64-bit machines.

Sounds like we cannot support this type without breaking changes somewhere, and they won't make any sense to Python, JS, PHP, Elixir, Ruby users.

Should we give up on the idea and document the decision in the issue?

@Zerpet
Copy link
Contributor

Zerpet commented Feb 16, 2023

Should we give up on the idea and document the decision in the issue?

Sounds good to me. I think we should just not have support for unsigned 64-bit integers.

The alternative would be to accept ulong types and encode them, doesn't really matter how i.e. l or L, and let the server interpret them as signed longs. This feels counter-intuitive and could lead to potentially obscure issues. I'd rather just not support them.

@thepunkoff
Copy link
Author

Sounds ok to me, too. Just a shame that uints, ushorts and sbytes are already supported, and this all can't be pretty :)

Also, as I can see, at least two clients for languages, that don't have unsigned types (and signed bytes), already will raise an error if they see unsupported values while decoding. Notice the absence of cases for ('u', 'i' ,'b'):

So the dotnet client can already crash some other clients with these types.

Zerpet added a commit to rabbitmq/rabbitmq-website that referenced this pull request Feb 17, 2023
Related to rabbitmq/rabbitmq-dotnet-client#1299

We have agreed to not support ulong values, and document
this as a limitation instead.

Signed-off-by: Aitor Perez Cedres <acedres@vmware.com>
@thepunkoff thepunkoff deleted the support-ulong-in-header-values branch February 20, 2023 10:27
mkuratczyk pushed a commit to rabbitmq/rabbitmq-website that referenced this pull request May 24, 2023
Related to rabbitmq/rabbitmq-dotnet-client#1299

We have agreed to not support ulong values, and document
this as a limitation instead.

Signed-off-by: Aitor Perez Cedres <acedres@vmware.com>
@Laurianti Laurianti mentioned this pull request Jan 26, 2024
11 tasks
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.

Impossible to use a ulong as a header value
5 participants