Open MeikelLP opened 6 months ago
Issues
185 New issues
0 Accepted issues
Measures
0 Security Hotspots
0.0% Coverage on New Code
0.0% Duplication on New Code
Failed conditions
D Reliability Rating on New Code (required ≥ A)
See analysis details on SonarCloud
Catch issues before they fail your Quality Gate with our IDE extension SonarLint
Relates to #11
The previous implementation used C# 10's static interface members which where very handy. Sadly they came with a limitation: You can no longer use that interface as type parameter.
This has several disadvantages:
The new implementation works like this:
PacketInfo
was simplified to no longer query data itself but require it to be inserted from outside (now only a data holder - no logic included)PacketDeserializerGenerator
andPacketSerializerGenerator
opened up some APIs to bestatic internal
which allows us to test them easily (Tests were added)Overall this PR improves testability and maintainability as well as performance.
1. Attempt
First attempt was to implement packets as
readonly ref structs
because they are allocated on the stack by default, are immutable and cannot be passed / boxed outside of scope. Sadly this does not really work because we need to do some magic to invoke the packet handlers and pass down the packets.Activator
or reflection in general cannot createref structs
and thus it's impossible to use a generic approach.Another way would be to use C# Source Generators but this implies the limit to have source access to the packets (no plugin in packets possible). Additionally a "packet handler manger" would need to be generated. One for each assembly. This is not really working out.
2. Attempt
Using heavy array and object pooling (powered by
Microsoft.Extensions.ObjectPool
most commonly used in ASP.NET Core) I was able to significantly improve performance per packet read. It still uses (cached) reflection to invoke handlers but they are very fast. Packets are reused and recycled per invoke.Here's a quick benchmark (1 packet read) of the packet readers:
The benchmark can be seen in PacketReaderBenchmark.cs
Afterword
In the future the generator still requires some improvements when it comes to diagnostics and validation of user types.