UmaDb.Client.Fsharp
0.1.0
dotnet add package UmaDb.Client.Fsharp --version 0.1.0
NuGet\Install-Package UmaDb.Client.Fsharp -Version 0.1.0
<PackageReference Include="UmaDb.Client.Fsharp" Version="0.1.0" />
<PackageVersion Include="UmaDb.Client.Fsharp" Version="0.1.0" />
<PackageReference Include="UmaDb.Client.Fsharp" />
paket add UmaDb.Client.Fsharp --version 0.1.0
#r "nuget: UmaDb.Client.Fsharp, 0.1.0"
#:package UmaDb.Client.Fsharp@0.1.0
#addin nuget:?package=UmaDb.Client.Fsharp&version=0.1.0
#tool nuget:?package=UmaDb.Client.Fsharp&version=0.1.0
UmaDb .NET Client
A high-performance .NET client for UmaDB, designed for Dynamic Consistency Boundaries (DCB).
Documentation: C# client guide — connection, concepts, recipes (append/read, consistency boundaries, projections, tracking, idempotent append), API reference, and managing client lifetime.
F# client: under development.
Architecture Decision Records (ADR)
ADR 1: Target Performance & Low Allocations
- Decision: Use
ValueTask<T>for the internal engine and gRPC transport viaprotobuf-net.Grpc. - Rationale: UmaDB handles high-frequency event streams.
ValueTaskgives zero-allocation paths for synchronous completions, reducing GC pressure.
ADR 2: Triple-Surface API (The Language Bridge)
- Decision: Expose different types for C# and F# through a Core library and an Wrappers.
- Rationale: C# and F# idiomatic code differs, thus different clients (wrappers) can align better to each idiom. Both sit on the same high-perf engine.
ADR 3: F# client uses task / taskSeq (not Async<'T>) as its primary async model
- Decision: The public F# client (
UmaDb.Fsharp) uses F#task/taskSeq(i.e. .NETTask/IAsyncEnumerable) as its primary async surface, especially for reads and streaming, rather than wrapping everything inAsync<'T>/AsyncSeq. - Rationale:
- Direct gRPC alignment: The generated gRPC stubs expose
TaskandIAsyncEnumerable<ReadResponse>with explicitCancellationToken. Usingtask/taskSeqlets the F# client sit directly on these types without extra adapter layers or duplicate cancellation channels. - Streaming & cancellation semantics: Long-lived reads/subscriptions are driven by explicit
CancellationTokens and gRPC stream lifetime.taskSeqkeeps this 1:1 with the transport;Async<'T>would introduce an additional implicit token (Async.CancellationToken) that does not map cleanly to gRPC. - Performance on hot paths: UmaDB clients are used in high-throughput consumers and projections. Every conversion between
Task/IAsyncEnumerableandAsync<'T>/AsyncSeqadds state machines, allocations, and potential context switches. Keeping the public surface ontask/taskSeqminimizes overhead in the streaming path. - F# ergonomics preserved: F# developers can still opt into
Async<'T>at their own boundaries (e.g.Task→Async<'T>viaAsync.AwaitTask, or materializingtaskSeqto a list), but the core library remains “close to the wire” and does not force that model internally.
- Direct gRPC alignment: The generated gRPC stubs expose
Managing UmaClient
Reuse one client per process — gRPC channels are meant to be reused (Microsoft guidance). Creating a client per call adds connection overhead.
- C#: Register
UmaClientas a singleton in DI; the host disposes it on shutdown. - F#: Create one client at startup (e.g.
use client = UmaClient.Connect(...)inmain) and pass it where needed.
For DI registration, subscription workers, and full API details, see the C# client documentation.
Performance
- Trimming: Compatible with .NET 10 trimming and AOT.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- FSharp.Control.TaskSeq (>= 0.4.0)
- FSharp.Core (>= 10.0.101)
- Grpc.Net.Client (>= 2.76.0)
- protobuf-net.Grpc (>= 1.1.1)
- System.Security.Cryptography.Pkcs (>= 8.0.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.