Uh oh!
There was an error while loading. Please reload this page.
Add NerdbankMessagePackFormatter - #1100
Conversation
Andrew Arnott (AArnott)
left a comment
There was a problem hiding this comment.
Thanks for doing all this work. You're providing invaluable feedback for the Nerdbank.MessagePack library's feature set as well.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Charles Willis (trippwill)
commented
Dec 27, 2024
Andrew Arnott (@AArnott) : Current test stats: 2157 Passed |
Current test results: Andrew Arnott (@AArnott) - Currently seeing a lot of test failures around exceptions and having difficulty tracing the issues. Many errors are caused by an NB.MP throwing b/c an exception is not serializable. While adding additional formatter configuration for the tests to pass, I'm seeing some The need to pre-register converters in the serializer without the ability to resolve and cache at runtime like legacy MessagePack-CSharp resolvers, is currently the cause of the most repeated builder calls. I suppose we could make a converter act similar to a resolver, or make some converters more open to supporting a wider set of types? Edit |
Charles Willis (trippwill)
commented
Dec 28, 2024
Benchmarks:
|
Andrew Arnott (AArnott)
commented
Dec 29, 2024
Seeing the exception type, message and stack trace usually helps me understand and suggest fixes for issues like this.
FYI I haven't looked closely at the core of your pull request yet, since I'm trying to stay 'OOF' 😉 so I can't make a firm recommendation at this point.
I recently removed the exception that is thrown when you register more converters after serialization has happened. But it still resets the converter cache so it's a runtime hit that should be avoided if possible. Is your concern mostly around generics? I'm still working on a better solution for that from NB.MP that I hope will make this simpler for you.
Historically, separating envelope from user data has been useful in protecting the integrity of the JSON-RPC protocol and our extensions, while allowing the user to have flexibility in how types are serialized. If we have just one serializer object, it seems the user will either be disallowed to customize how types are serialized that we internally must serialize, or the user's customizations could invalidate the objects we serialize for the envelope. And this set of sensitive types may change over time as we change what or how we serialize objects as part of the core protocol or the exotic types. If I'm missing the mark of what you're thinking of, please correct me.
Most of those look pretty good. The last one seems to mix in making the connection itself, which seems likely to be noisy. But I have no idea why NB.MP would make the process of connecting so much slower than the other libraries. Do you? |
Charles Willis (trippwill)
commented
Dec 29, 2024
Totally makes sense.
Mostly, yes. With MP-CS resolvers, the right formatter is found by working through an ordered list of resolvers for any given type. This allows for behaviors like a resolver intercepting intrinsic rpc-marhalables before they matched to a more conventional formatter. Same for things like Pipes and Streams as arguments or return types. And IAsyncEnumerable as a property on a class. With NB.MP, a type like Basically, not being able to intercept the exotic types as they are seen (for best perf) means the StreamJsonRpc consumer needs to be very explicit up-front.
Not yet :-)
Totally understandable. I should probably step away from this myself for awhile. |
Charles Willis (trippwill)
commented
Dec 29, 2024
Latest Test Results: |
Charles Willis (trippwill)
commented
Jan 1, 2025
Latest Test Results: |
Charles Willis (trippwill)
commented
Jan 1, 2025
Test Results: 2275 Passed |
Charles Willis (trippwill)
commented
Jan 1, 2025
Latest benchmarks hint that there is a correlation between time and number of serializer runtime register calls. In the latest commit, many more converters and new sub type maps are added in the ctor of NerdbankMessagePackFormatter. The time could also be a result of the calls to converter resolvers. |
Andrew Arnott (AArnott)
commented
Jan 2, 2025
Does this benchmark include the RegisterConverter calls themselves? If so, we should probably isolate that in a "connection creation" benchmark, leaving a benchmark that measures only the incremental cost of an RPC call. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Andrew Arnott (AArnott)
commented
Mar 29, 2025
FYI I've been building more on your branch with my own branch name. I'll push a bunch of commits at once soon, since I have only one last test failure. 🎈 |
0f1a767 to
10be435CompareAndrew Arnott (AArnott)
commented
Mar 29, 2025
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
cec80d1 to
3ec9b93CompareAndrew Arnott (AArnott)
commented
Mar 29, 2025
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
3ec9b93 to
c900c6bCompareAndrew Arnott (AArnott)
commented
Mar 29, 2025
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
c900c6b to
b7bc374CompareAndrew Arnott (AArnott)
commented
Mar 29, 2025
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
b7bc374 to
d180b4cCompare|
Azure Pipelines successfully started running 1 pipeline(s). |
Named args are frequently used with C# anonymous types, for which 'type shapes' cannot be created. Since they were passed in via parameters declared as `object`, reflecting over them is not trim-safe either (at least, the linker doesn't think so). The new `NamedArgs.Create` API makes it easy to wrap any object (including anonymous types) such that it is trim-safe and avoids individual formatters having to understand how to reflect over them. I also added `[RequiresUnreferencedCode]` to the method overloads that just take `object` since resorting to reflection will never be trim safe. But for the callers that were passing in _dictionaries_ (which _are_ always trim safe), I added overloads _without_ the new attribute so that they can use them in trimmed apps. Fixed the last trim warning
3da5ee2 to
367cc6bCompareAndrew Arnott (AArnott)
commented
Jul 29, 2025
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Andrew Arnott (AArnott)
commented
Jul 29, 2025
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Uh oh!
There was an error while loading. Please reload this page.
znakeeye
commented
Sep 10, 2025
No nuget package available for this? My project doesn't recognize |
Andrew Arnott (AArnott)
commented
Sep 10, 2025
True. We haven't released this change in a package. In fact, we recently decided to delay shipping this another release, so you can watch #1280 for when we bring it back. Hopefully in about a month. |
Add an
IJsonRpcMessageFormatterimplementation that uses Nerdbank.MessagePack. This serializer has better startup time and is AOT-safe. This alone won't make StreamJsonRpc as a whole AOT safe, but it's a step in that direction.