-
Notifications
You must be signed in to change notification settings - Fork 58
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 Simplification #171
Conversation
IBufferWriter is part of the standard runtime and since we're not using the property introduced by our interface ICountableBuffer (which extends IBufferWriter)there is no reason to keep that dependency on the public interface.
* Simplified INatsSerializer a little more. (Serialize method's return value wasn't used) * Removed the default JSON serializer which was serializing any object using reflection. Reflection isn't possible with native AOT. This also makes serialization more explicit. * Added a UTF8 primitives serializer in the default serializer chain to cover simple use cases like sending strings or ints. * Added JSON serializer contexts for JS, Obj and Services models.
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.
I've only taken a quick look because I'm vacationing and have unfortunately little time right now. Left a few comments but nothing major.
I think this is an improvement. But I'm still not convinced that the non-generic ISerializer
is the best interface, both in terms of discoverability of the serialization API and performance.
|
||
var span = bufferWriter.GetSpan(128); | ||
|
||
// int |
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.
How were the supported types chosen? int
and double
seem kinda arbitrary.
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.
Somewhat is. Ideally I wanted to support all types Utf8Parser
supports.
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.
That is a neat idea, I like the idea of supporting all of the Utf8Formatter/Parser types
throw new NatsException($"Can't serialize {typeof(T)}"); | ||
} | ||
|
||
Next.Serialize(bufferWriter, value); |
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.
What's the use case for this chaining? To have composition support for serializers I presume?
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.
Yes, composition and reuse. Though I realized it doesn't need to be enforced by the interface. So I removed the Next
property from the interface and it really is an optional convention now.
{ | ||
Utf8JsonWriter writer; | ||
if (_jsonWriter == null) | ||
if (_context.GetTypeInfo(typeof(T)) is JsonTypeInfo<T> jsonTypeInfo) |
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.
A minor downside of the non-generic INatsSerializer
is that it requires a dictionary lookup for the JsonTypeInfo<T>
as opposed to a generic serializer where the required type info object would be known.
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.
We could have a generic interface where we chain multiple types when used in connection options.
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.
I gave this a go but there is way too much change. I'll leave it to another PR.
Co-authored-by: Jasper <[email protected]>
Co-authored-by: Jasper <[email protected]>
Co-authored-by: Jasper <[email protected]>
Thank you @jasper-d very helpful. Already commited your suggestions. Will have a look at your other comments tomorrow. Have a nice vacation 🍹 |
Also removed method inlining on getters (based on Jasper's advice: Presumably JIT should always inline simple field accesses and the other getters look like they are likely inlined without AggressiveInlining when on a hot path.) Thank you @jasper-d
Note that chaining serializers is implemented by convention and doesn't need to be enforced by the INatsSerializer interface since the next serializer would not be exposed to external users of the interface.
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.
I like the approach!
What about people who don't care about trimming/AOT? Should we offer a regular JSON Serializer that doesn't depend on defining a JSON Context? Could that be in the same assembly or would we need to move it out to another assembly that does not have <IsTrimmable>true</IsTrimmable>
|
||
var span = bufferWriter.GetSpan(128); | ||
|
||
// int |
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.
That is a neat idea, I like the idea of supporting all of the Utf8Formatter/Parser types
I think so. |
Yes, if it would introduce problems with AOT we should definitely isolate it somewhere like that |
All primitives supported by Utf8Parser and Utf8Formatter are implemented.
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.
LGTM!
https://github.com/nats-io/nats.net.v2/blob/serialization-proposal/docs/documentation/serialization.md
INatsSerializer
interface (usingIBufferWriter
)resolves #92 - NativeAOT support
resolves #137 - Reconsider serialization approach