I'm trying to understande MessageToByteEncoder usage. If messages are large, say 32MB then it seems quite costly to copy all data from one ByteBuffer to a new one. Is there something I'm missing here? Is it ok to make reference copies using getSlice instead? I.e. is the original data safe to use or will it be discarded?
@Marcu5 exactly what Cory says. Commenting just because I happened to have had what appears like a similar use-case yesterday: If you already got most of the payload in a ByteBuffer and you just want to prepend some framing information or so, then you're probably better off not using MessageToByteEncoder. You can just write a ChannelOutboundHandler, write out the framing information and then just hand through the ByteBuffer you already got. Example here.
Thank you, Johannes. That's exactly my use case. I'll go ahead and provide the framing information in a separate .write(data:promise:) call, as in the example linked.
For future reference, when should the MessageToByteEncoder actually be used, i.e. for which use-cases?
@Marcu5 great! MessageToByteEncoder is useful if you have a “message” for example your own data type (usually a struct) that you want to encode to the wire protocol. For example you might use JSONEncoder in there. But currently, if you already have many bytes as ByteBuffer it’s not super useful because you wouldn’t want to copy them (as you said). Possibly, we could in the future add API that supports this. But then, writing simple encoding ChannelOutboundHandlers is actually simple enough...
Thank you for the eloquent replies, it all makes sense now. Generics had me confused for a bit since I didn't consider the notion of having other types than ByteBuffer as source.