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 issues with Transaction upsert operation #2016
Serialization issues with Transaction upsert operation #2016
Comments
With Java SDK
Using GRPC Execute Transaction. Saves it as a string and also we can see the extra escaped quotes.
|
My opinion is to go with fix .1 in the runtime. |
@yaron2 All three steps of the fix are necessary. |
Ok, just making sure we're not doing a Redis only fix here. We need to make sure that the runtime does the right thing. |
Here is the behavior with .net sdk:-
With TransactionState Upsert operation:- With Transaction APIs, get after a save state results in a deserialization exception:- == APP == at System.Text.Json.ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type propertyType) == APP == at System.Text.Json.JsonPropertyInfoNotNullable`4.OnRead(ReadStack& state, Utf8JsonReader& reader) == APP == at System.Text.Json.JsonPropertyInfo.Read(JsonTokenType tokenType, ReadStack& state, Utf8JsonReader& reader) == APP == at System.Text.Json.JsonSerializer.ReadCore(JsonSerializerOptions options, Utf8JsonReader& reader, ReadStack& readStack) == APP == at System.Text.Json.JsonSerializer.ReadCore(Type returnType, JsonSerializerOptions options, Utf8JsonReader& reader) == APP == at System.Text.Json.JsonSerializer.Deserialize(String json, Type returnType, JsonSerializerOptions options) == APP == at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options) == APP == at Dapr.Client.DaprClientGrpc.GetStateAsync[TValue](String storeName, String key, Nullable == APP == at DaprClient.Program.GetStateAfterTransactionAsync(DaprClient client) in /Users/vinayada/dapr/dotnet-sdk/samples/Client/DaprClient/Program.cs:line 133 == APP == at DaprClient.Program.Main(String[] args) in /Users/vinayada/dapr/dotnet-sdk/samples/Client/DaprClient/Program.cs:line 55 == APP == at DaprClient.Program. (String[] args) |
Also, note that the data is being stored differently to the state store by Java and .net sdks. Therefore, set by one and get by other would fail too. |
the go-sdk has an explicit upsert test to validate this in a unit test but it looks like when used with a state component backed by Redis service the serialization issue is there: == APP == expected: { "message": "hello" }
== APP == got : "\"{ \\\"message\\\": \\\"hello\\\" }\"" |
I was able to replicate in PostgreSQL as well... that's after fighting Mongo replicaset for 20 min (required for transaction support). Looks like this is Dapr core level issue. == APP == expected: { "message": "hello" }
== APP == got : "\"{ \\\"message\\\": \\\"hello\\\" }\"" |
HTTP transaction api (including actor transactional api) deserializes the entire payload to extract operation, value, and key, so value is non-string or non-byte array value when user pass non-string/non-byte array. then component serializes this non-string and non-bytes value. But grpc apis requires no deseralization to extract value. When Dapr passes this value to the existing redis component, redis component will serialize this to base64 string (which is json primitive type conversion). if we convert this to string, then serializer will add double-quotes. e.g. []byte("hello") -> ""hello"" I agree upon the potential fix that @mukundansundar. component needs to take care about deserialized value (for http), raw value (for grpc) accordingly. we need to find the way to minimize the impact on this change. |
My bad, fat-fingered trackpad click :( |
In what area(s)?
/area runtime
What version of Dapr?
0.10.0
Expected Behavior
When a state is saved via the the executeTransaction method via GRPC,
Multi
method implementation for redis state store, and the state is again read in via the getState API, there is a deserialization issue.Found during implementation of the transaction API for Java SDK.
Actual Behavior
State saved via transactional API or the normal save state API should be read correctly via the Get State API
Steps to Reproduce the Problem
Potential issue
In the runtime, the
req.Value
parameter is converted to string and then the Multi interface is called.Specifically in redis component, the String value is marshaled again.
When the value is an object, this causes additional escape characters to be added and finally the object is only deserialized once into a string which is where the String Args constructor exception comes from.
Example of escape characters introduced:
data: "\"{\\\"propertyA\\\":\\\"data in property A\\\",\\\"propertyB\\\":\\\"data in property B\\\"}\""
instead of normal serialization into
data: "{\"propertyA\":\"data in property A\",\"propertyB\":\"data in property B\"}"
Potential fix:
code to fix save state flow
The text was updated successfully, but these errors were encountered: