sans-io pattern in .NET library
I'm a big fan of writing sans-io implementations https://sans-io.readthedocs.io/ of various protocols which help focus on the actual protocol details while leaving the IO questions to other libraries that implement the code. I am curious what some people might recommend for dealing with the message buffer, that is bytes that are produced to be written to the target and bytes that should be read from the target. I am interested in efficient ways to provide this buffer without producing unnecessary copies and ensure it doesn't slow things down. I was thinking that System.IO.Pipelines would be good for this but curious if there are potentially other options.
5 Replies
i've been creating my clients with this kind of isolation for years, it really should be more widespread
Yea I have one currently for LDAP in .NET but it's somewhat tied to a PowerShell module. I'm contemplating splitting it out into a dedicated nuget package but this is the part I'm trying to figure out a good pattern for. It currently uses System.IO.Pipelines but I'm not sure if there's potentially a better alternative out there
i found myself with this choice a few times
since i started with net framework i just used events in the beginning
then switched to just
Func
s
then i tried with more advanced stuff like pipelines
it depends on a lot of factors, how much retrocompatibility you want to have
how much data will be going through
how much do you want to complicate life of people using it, becaue pipelines are powerful but i think not many people are used to it
also i think pipelines would be used just in the more physical layer or the most bottom two, because after that probably you would already have some kind of modelThat's my apprehension with Pipelines is that it's not a simple thing to work with but the alternative of just accepting a byte array and emitting one seems wasteful from a memory/copy perspective
there are some ways to approach this i think
you can return value objects (like structs) but you have to limit the amount of bytes or it will be allocated on the heap
you can reuse buffers but you need to pass them around
you can do other stuff too but im too tired to think
i would say don't worry too much about this because already sockets and com ports and other clients are already optimized, i would try some ways, benchmark them, and then make a judgement on usability vs performance