Description
This is effectively the same problem as #79560 but for the transport layer.
Sending and receiving a large message on the transport layer currently entails buffering the whole message in full before sending and reading. With recent improvements to field caps and can_match we're now working with more large transport messages and are seeing field_caps messages of O(100M) in some cases. Also, we've already been dealing with large cluster state messages for a while. The way things are implemented right now when working with uncompressed transport messages, sending a 100M message costs us more than 200M in peak heap usage on both sender and receiver of the message in cases like field caps where we're paying for both the message object itself on heap as well as the fully buffered message.
As has been discussed previously in various situations, I think we need to improve the network layer to support more efficient streaming serialisation and deserialisation to avoid buffering full messages going forward. I don't think we would necessarily have to change the over the wire format to do so since the current format already contains quite a bit of size information, though adjustments to the format could make it easier to do streaming reads.
Concretely I would suggest the following:
- serialize messages on the transport layer again to avoid wasting buffers before it's at least likely that they can be flushed to the network like we had in Serialize Outbound Message on Flush #57084 (the problems that had us revert this change have now been resolved and we could easily bring it back)
- but go even further and only serialize a part of the message that we expect to be able to flush before writing it to the wire, then continue serialising once the channel is writable again
- look into deserialising message as we read them instead of buffering them in full up-front. Even with the current format this should be possible for things like field-caps albeit at the cost of re-reading parts of a message (we can optimistically try to deserialise and if we fail to read part of a message in full retry once we have more bytes buffered)
relates #77466