Sync-prepared batches account for the vast majority of outbound packets. Avoiding these useless objects further reduces the overhead of zero-compressed packets, as the creation of these objects is a significant part of the overhead for these cases.
closes#6157
closes#5670
I'm not super happy with this fix, since it can still be broken if StandardPacketBroadcaster is replaced by something else. However, fixing that problem is probably going to require internal BC breaks, which are not suitable for a patch release.
In refactors during PM4, I stripped out packet buffer caching, as it was problematic when events alter packets in undetectable ways.
However, I never cleaned this part of the code up properly after enabling DataPacketSendEvent to include multiple packets and multiple targets, so we were still individually encoding the packet(s) for every single session if the sum total of the sizes was below 256 bytes.
This change encodes packets once in the StandardPacketBroadcaster and retains their buffers to post to the session's send buffer directly if the resulting batch is below compression threshold.
This code is still not optimal (see ##5589), but fixing this brings broadcasting performance back to PM3 levels, without any of PM3's problems.
in the normal case, all sessions will share the same PacketSerializerContext and Compressor, so this code will be the same as before
However, for the multi-protocol hackers out there, this should reduce the maintenance burden (@Driesboy) since now only the PacketSerializerContext needs to be maintained. I recommend a separate PacketSerializerContext for each protocol (perhaps put the protocol version in the serializer context too, if you need it for some reason).
while this is a bit hacky outside of the protocol namespace, it makes it much easier to use the protocol library for alternative purposes, such as for a client or MITM proxy.
It also removes all but one remaining core dependency of the protocol library, making it very close to being able to be separated from the server core entirely.
this gives a bit more control over how packets are broadcasted, which might be useful if the batch format changes (e.g. adding a length prefix) for multi version.
This really ought to be unique to a protocol context instead of a network interface, but for now this is the best we can do.