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
Serialization of 64bit values are truncated #3837
Comments
This issue has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in the next 7 days unless it is tagged (pinned, good first issue, help wanted or triaged/resolved) or other activity occurs. Thank you for your contributions. |
I have this problem too. |
Any update? |
Yeah I got the same problem too. Could any one tell me how to fix it? |
I triaged this to be fixed in 1.6. cc @artursouza |
Is this a runtime or SDK issue? |
Runtime |
Serialization is used in runtime.go, but when it encounters 64bit it automatically identifies Number as float64. For example:
json.Unmarshal will use float64 to handle the problem, and you'll need to change the method to display the declaration.
|
Related, possible: json-iterator/go#510 |
@yaron2 You can consider using the following code to solve.
Use the func (*Decoder) UseNumber method to deserialize the numeral type of json, instead of directly converting to float64, convert to json.Number, json.Number internal:
|
Thanks @hueifeng. @artursouza after looking at this, I recommend we move away from Moving to |
LGTM |
@hueifeng would you like to contribute this change? |
I can do it. |
E2E tests are not passing in the PR, moving to 1.7 |
Moving to 1.7 because we are cutting RC for 1.6. |
/assign |
Dapr/dapr does not have a problem. I tried putting telemetry around pub (pkg/grpc/api.go) and sub (pkg/runtime/runtime.go) code to check what data is being sent and received. Example data sent from application: {"int32":1041701776,"uint32":1041701776,"int64":637831257272814404,"uint64":637831257272814404,"base64long":"RAtjLCYI2gg=","base64int":"kBsXPg=="} On Dapr side, while sending the data, the raw bytes from Marshaling the struct gets its map[data:map[base64int:kBsXPg== base64long:RAtjLCYI2gg= int32:1.041701776e+09 int64:6.378312572728145e+17 uint32:1.041701776e+09 uint64:6.378312572728145e+17] On Dapr side, while receiving the data, the raw bytes itself have incorrect data (as in shubham1172/dapr-serialization-issue's readme). Thus Unmarshaling with map[data:map[base64int:kBsXPg== base64long:RAtjLCYI2gg= int32:1041701776 int64:637831257272814500 uint32:1041701776 uint64:637831257272814500] The root cause is the Should we create a separate item to move away from jsoniter to encoding/json? |
I did some more research, and this will not be a breaking change. The only change that this PR introduces is in the unmarshalling of the CloudEvent data from the PublishEventRequest in PublishEvent (api.go) Earlier, this unmarshalling resulted in data loss while converting 64-bit values to 53-bits float (as per JSON). Now, it uses After unmarshalling the CloudEvent's data, it's packed into the PublishRequest as The same thing is being read as Since the public API contracts are not changed, this won't affect anything external. |
Adding some more data here for comparison. All these are requests with CloudEvents in JSON format (other CloudEvent formats/rawPayloads are unaffected). Before the PR: // data received by PublishRequest
{"int32":1778635775,"uint32":1778635775,"int64":637715205845980876,"uint64":637715205845980876,"base64long":"zJZQ2Jme2Qg=","base64int":"/9MDag=="}
// data marshalled by PublishRequest
{"int32":1778635775,"uint32":1778635775,"int64":637715205845980900,"uint64":637715205845980900,"base64long":"zJZQ2Jme2Qg=","base64int":"/9MDag=="}
// data receievd by Subscriber
{"int32":1778635775,"uint32":1778635775,"int64":637715205845980900,"uint64":637715205845980900,"base64long":"zJZQ2Jme2Qg=","base64int":"/9MDag=="} After the PR: // data received by PublishRequest
{"int32":1228499251,"uint32":1228499251,"int64":637834811545047664,"uint64":637834811545047664,"base64long":"cFKFt2EL2gg=","base64int":"M2k5SQ=="}
// data marshalled by PublishRequest
{"int32":1228499251,"uint32":1228499251,"int64":637834811545047664,"uint64":637834811545047664,"base64long":"cFKFt2EL2gg=","base64int":"M2k5SQ=="}
// data received by Subscriber
{"int32":1228499251,"uint32":1228499251,"int64":637834811545047664,"uint64":637834811545047664,"base64long":"cFKFt2EL2gg=","base64int":"M2k5SQ=="} |
@mukundansundar can you please un-tag the PR as |
In what area(s)?
/area runtime
What version of Dapr?
edge: output of
git describe --dirty
starting Dapr Runtime -- version edge -- commit b1cad9a
Expected Behavior
Sending 64bit values with pub/sub are expected to arrive unchanged.
Actual Behavior
Receiving 64bit values are truncated in the trailing two decimal digits.
Best guess is that the serialized json has a max string-length for numbers.
Steps to Reproduce the Problem
I have posted a reproducible setup, based on Docker, with instructions:
https://github.com/kskem/dapr-serialization-issue
Recap of the problem:
Release Note
RELEASE NOTE: FIX Bug in runtime.
The text was updated successfully, but these errors were encountered: