akka.net
akka.net copied to clipboard
System.IO.Pipelines as Akka.IO Implementation Layer
As it looks that System.IO.Pipelines will soon reach .NET corefx repository, we could take a look at it and check if we could use for our remote layer.
Quick recap: System.IO.Pipelines is a low-alloc socket library which originates from Kestrel - Asp.NET high-performance HTTP layer. There's a lot of work which happened around in .NET to provide a low-alloc/alloc-free access used here, including heavy use of Span<byte>, Memory<byte> and ByteSegments (something similar to our impl of ByteString, but mutable). Pipelines also have ability to compose custom user behavior by exposing IPipe interfaces, see:
- An experimental Redis client on top of pipelines: https://github.com/mgravell/RedisPing
- Websocket protocol implementation: https://github.com/mgravell/Pipelines.WebSockets
Another thing I'm working aside is a zero-cost abstraction layer over Hyperion, which could potentially work together with IOutput and WritableBuffer - pipelines API for reading/writing binary data. Hopefully other serialization libraries will go this path as well.
All of this would fit well with integration of Akka.NET with new .NET ecosystem i.e.:
- Let a
ByteStringuseReadOnlySpan<byte>instead ofArraySegment<byte> - Replace/extend our
IBufferPoolwith globalByteArrayPoolfrom System.Memory namespace. - Replace/extend our serializers API to work with new low-alloc APIs.
- Take a look at pipelines and think how we could integrate them with our TCP/UDP actors - this will be probably hard, as pipelines have their own (plugable) multi-threading control mechanism over sockets, but maybe we could reuse parts of the API or create our own integration which will allow us to create a System.IO.Pipelines socket server backed by Akka.NET actor concurrency model.
This is nothing sure atm, but I think that ADO.NET soon also will make use of those as well.
@Horusiath question: think it'd be easier to prove this as a concept inside of Akka.IO initially? Fewer moving parts than Akka.Remote.
I'm open to the idea.
One of the problems our serialization / networking layer has right now is that all of the components involved have their own separate concepts of things like buffers, pooling, etc... Protobuf, DotNetty, JSON.NET, Hyperion. If these separate components adopt some unified abstraction like Span, it'll make it less expensive for us to keep our high degree of configurability without having to make the same performance compromises we have to today.
Anyway, I see this as a long term project since it'll inevitably depend on other third party libraries adopting these features as they are RTMed, bugs are found, etc - so the time horizon for this might be quite long before it can be release-worthy. Still worth doing.
@IgorFedchenko is investigating replacing our current SocketAsyncEventArgs implementation with System.IO.Pipelines inside Akka.IO. The plan is to dramatically increase the throughput of Akka.IO first and then use it as the transport layer for https://github.com/akkadotnet/akka.net/issues/4007 in a subsequent set of PRs.
Renamed the issue to reflect that - the spirit of @Horusiath's idea remains the same, but we're looking at implementing it in Akka.IO first and then Akka.Remote second.
Based on the work @IgorFedchenko did, looks like this is out of scope for v1.4.0. Need to add .NET Standard 2.1 targeting to get any real benefit out of this.