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
Coreclr compatibility: Implemented Json.Net fallback serializer #1047
Coreclr compatibility: Implemented Json.Net fallback serializer #1047
Conversation
987fb9d
to
4bef196
Compare
@@ -36,8 +37,8 @@ namespace Orleans.Providers.Streams.AzureQueue | |||
internal class AzureQueueBatchContainer : IBatchContainer | |||
{ | |||
private EventSequenceToken sequenceToken; | |||
private readonly List<object> events; | |||
private readonly Dictionary<string, object> requestContext; | |||
public readonly List<object> events; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is going to be completely unmanagable.
If we want internal runtime types to be Json serializable, we need to find a better/robust/testable way to enforce that. Otherwise, it will keep breaking. Look at the 5 times we already broke the pub sub state json serialization, since we used the approach of marking fields public. There are much better alternatives.
I suggest to open a separate issue and discuss it. I am sure people in our community have better expertise how to make sure their internal types are json-able.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Following the way of fixing PubSubStateGrain was quite bad idea.
#if DNXCORE50 | ||
throw new OrleansException("Can't use binary formatter as fallback serializer while running on .Net Core"); | ||
#else | ||
serializer = new BinaryFormatterSerializer(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does not seem like we need to allocate a new BinaryFormatterSerializer
instance every time it is called, right? It is pretty much stateless, just a call through into Ser/Deser/Copy methods. So better allocate once and return, save some GC.
Same applies to OrleansJsonSerializer
.
Serialization code is of course the most sensitive to perf, as it is on the hottest path.
140bb89
to
a4e0006
Compare
Updated. Made few more internal types json serialization friendly. |
} | ||
|
||
var numAgents = await mgmt.SendControlCommandToProvider(adapterType, adapterName, (int)PersistentStreamProviderCommand.GetNumberRunningAgents); | ||
Assert.AreEqual(2, numAgents.Length); | ||
int totalNumAgents = numAgents.Cast<int>().Sum(); | ||
int totalNumAgents = numAgents.Select(n=>int.Parse(n.ToString())).Sum(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove those n=>int.Parse(n.ToString()
.
We should not need to go via string.
If there is a problem with int to long, we can fix that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When serializing with binary formatter the resulting array contains ints and when with Json.Net one - longs.
At a quick glance, I'm seeing over a hundred Orleans classes marked [Serializable]. I'd like to believe they are all covered by tests, but I'm not that confident. I don't know any simple way to vet this change. |
|
a4e0006
to
3e158f1
Compare
Commits squashed. |
5790bac
to
b222230
Compare
Removed some allocations in the serialization code using thread local serializers instead of creation of the new ones on each serialization\deserialization, the number of GC collections of the zero gen on benchmark with deep copy of POCO decreased by ~7% but performance for binary serialization for some reason dropped by 15%. Will create separate PR for this later, if needed. Also, seems like Json.Net 2 - 3 times faster than binary formatter and causes lower GC pressure (2x less collections of the zero gen in comparison to the |
bf78197
to
b222230
Compare
"Cann't use binary formatter as fallback serializer while running on .Net Core, will use Json.Net instead"); | ||
} | ||
|
||
useJsonFallbackSerializer = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.useJsonFallbackSerializer = true, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, i replaced field useJsonFallbackSerializer with IExternalSerializer fallbackSerializer.
OK, so I have a couple of comments:
I would like this PR to be accepted after #1052. |
b222230
to
06b86c1
Compare
Updated & Squashed. Left |
Looks good. Going to merge. There is still an open question if all our internal types are json-serializable or do we miss any. |
Implemented Json.Net fallback serializer
Thank you @dVakulen ! |
I planned to merge it post 1.1.0. That's why I assigned the vNext milestone to it. |
Ohhhh... Anyway, I think this PR was safe. It added json as an alternative fallback serializer, but the binary serializer was still the default one, and it did not change. |
@gabikliot Thank you for the review! |
Related to #368.
Default fallback serializer is
BinaryFormatter
, using of the Json.Net one can be configured through boolean property "UseJsonFallbackSerializer".