-
Notifications
You must be signed in to change notification settings - Fork 476
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
Fix short integer encoding #359
Conversation
This commit also changes signedness of the long integer. From now, every integer is encoded as a signed one.
@arkq are you aware of the errata document? The 0-9-1 spec is known to have inconsistencies and contradictions when it comes to table encoding. At this point client library maintainers are better off by following what the Java (and .NET, and Ruby, and many other) clients use than blindly following the spec. The prefix for short signed integers indeed seems to be an |
I strongly oppose this change. What needs to change is Here's a list of popular clients that encode strings using By introducing this change you will break this client's interoperability with those client and gain interoperability with @squaremo would you agree with me? |
@michaelklishin thanks for the errata link. I was not aware of this document. During my battle with this strange bug (encoding incompatibilities), I've stumbled upon 0.9.1 spec and I've thought that it is the "master". If you say, that Pika is a way to go, I will see if it is possible in my case. Many thanks for such a quick response! I'm closing this PR as invalid. |
@arkq thank you. I completely understand that this is very confusing. The AMQP 0-9-1 spec had a rough childhood. |
@michaelklishin Yes I agree; the codec here is carefully crafted to be compatible with RabbitMQ and do what (most) other client libraries do. Unfortunately, the reason that one has to take a lot of care also means that it's not at all obvious why it's the way it is! |
After some investigation, I have learned, that pika is NOT a way to go (pika-0.10.0) if one wants interoperability with clients conformant with AMQP 0.9.1 + errata. Unfortunately, that was after, I've ported everything to pika... :) So, for anyone who has stumbled upon similar issue, the solution is: PS. PS2. |
We intend to work on Pika instead of moving the tutorials for other clients. Pika is certainly fine as far as interoperability goes in most places. Attribute tables was or still is an edge case in most clients. |
@michaelklishin that's fine. Tutorial is only an example (imho). It could have been written in a pseudocode as well, it would serve its purpose. However, I'm not complaining about the tutorial, but about the list of RabbitMQ libraries which is kinda misleading (for edge cases). <cool-story> Maybe the solution would be to change the amqp.node after all. E.g.: Encode integers in a compatible way with all clients - as an integer. Decoding will stay as it is now. This would be similar to Pika - which for encoding uses an intersection of types from 0.9.1 and 0.9.1-errata. In such a way there is 100% guaranteed compatibility with all clients. |
Since JavaScript only has the one numerical type, double, I made a guess about what was the most useful way to encode numerical values: by prioritising precision, then size of encoding, more or less. But it's impossible to get this right for everyone. (Note for protocol designers: don't include a "generic" encoding for values.) There's a suggestion that may turn into a PR: #358. This would let you specify that a value is specifically a long, or short, or whatever. Possibly I ought to have just required people to do this all along! (But then people using other dynamic languages would have found it less convenient, ho hum). |
For JS it would be a little bit strange. Like you've said, there is only one numerical type. However, it is possible to determine whether numerical value is an integer or not. So this approach of encoding floats and integers in a separate way is OK (IMHO). I've seen issue #358 before. It would be possible to mitigate my problem by using integer (int32). And to be fair, we've got exactly the same problem as described in the issue #358. In fact this problem appears in Go as well. However, right now I don't care much about the encoding. Changing Python library has resolved my issues. And the problem with dynamically selected integer type is quite easy to overcome anyway. I will not bump this thread any more. Once again many tanks to @michaelklishin, who has pointed me in a right direction - amqp spec incompatibilities. |
@arkq that's borderline overkill and an overly smart solution. Dynamically typed languages will always struggle with the plethora of numerical types available in/to their statically typed counterparts. JavaScript is particularly limited in this area. Unless you have to use headers exchanges (which is an exception, not the norm), I'd recommend sticking your values into message payload, and encoding the entire thing using protocol buffers. I think the idea in #358 is quite good, given the circumstances. |
Messages encoded with this library are not conformant with AMQP specification - such an incorrect message might crash client (written in other language, in my case py-amqp-1.4.9) which is conformant with the AMQP 0-9-1 specification.
In short:
s
is for short string, not for short integer. For signed short integer isU
.Reference:
https://www.rabbitmq.com/resources/specs/amqp0-9-1.pdf (Technical Specifications, page 31)
PS.
This commit also changes signedness of the long integer. From now, every integer is encoded as a signed one.