ID | IEP-78 |
Author | |
Sponsor | |
Created |
|
Status | ACTIVE |
Ignite 3 needs thin client drivers in different languages.
This proposal lists design consideration and implementation details for Ignite 3 .NET Thin Client.
Ignite 3 is in the alpha stage, we don't know the final release date. Currently (September 2021) the only supported LTS version of .NET SDK is .NET Core 3.1, which implements netstandard2.1.
At the same time, newer SDKs (.NET 5 and upcoming .NET 6) don't introduce anything important for us. Essential performance-oriented APIs (Span<T>, Memory<T>, ref struct) and async network APIs are available in netstandard2.1.
There is also .NET Framework (Windows-only) which is a part of Windows and follows the same support policy (.NET Framework 4.8 is supposed to be supported for many years to come). We are not going to target this in alpha stages to simplify development.
When the release time comes:
More info:
Use Apache.Ignite as the main assembly name and root namespace. We are not going to have thin/thick client separation or a standalone executable in 3.0.
The only dependency is MessagePack-CSharp. The library is performant, lightweight, and has no transitive dependencies. Primitive APIs are based on Span<T> and Memory<T> and don't allocate (except for ReadString).
Ignite 2.x uses a custom async engine with a dedicated thread and manual event loop management.
This is no longer required because standard Socket API provides async methods (Socket.ConnectAsync, NetworkStream.ReadAsync and WriteAsync), and the event loop is handled by SocketAsyncEngine, which shares resources across multiple active sockets.
DotNetty was considered (a proven .NET port of Netty, used by Akka.Net), but it does not provide much improvement over the standard API for our use case.
Do not provide synchronous wrappers for asynchronous API implementations. Example: do not provide ITable.Get method that simply calls ITable.GetAsync().GetAwaiter().GetResult(). Most of the APIs involve network IO and are implemented asynchronously.
Reasoning:
Buffer pooling is essential to reduce allocations and GC pressure when handling network IO. System.Buffers.ArrayPool<byte> should be used instead of allocating new byte arrays.
Note that ArrayPool had 1M elements limit that has been removed in .NET 6: https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-6/#buffering
Adopt connection reliability proposals from 2.x:
Use default Microsoft code style, enforced by StyleCop analyzers (code won't compile if there is a violation).