Skip to content

[.NET] Add Databricks Zerobus Ingest SDK for .NET#532

Open
nalyd2 wants to merge 3 commits into
databricks:mainfrom
nalyd2:feat/dotnetv1
Open

[.NET] Add Databricks Zerobus Ingest SDK for .NET#532
nalyd2 wants to merge 3 commits into
databricks:mainfrom
nalyd2:feat/dotnetv1

Conversation

@nalyd2

@nalyd2 nalyd2 commented Jul 17, 2026

Copy link
Copy Markdown

What changes are proposed in this pull request?

WHAT: Adds the .NET SDK (dotnet/) as a new wrapper language for the Zerobus Ingest SDK, alongside the existing Rust, Java, Python, Go, TypeScript, and C++ SDKs.

The SDK wraps the Rust C FFI (rust/ffi/) via P/Invoke with the following major components:

  • Native interop layer (Native/): P/Invoke declarations for all FFI functions, C struct marshaling, SafeHandle subclasses, cross-platform native library resolver
  • Core SDK (ZerobusSdk, StreamBuilder): Fluent builder API with typed sub-builders for JSON, Protobuf, and Arrow Flight streams
  • Stream types: ZerobusJsonStream, ZerobusProtoStream<T>, ZerobusArrowStream (Beta), all thread-safe with ReaderWriterLockSlim
  • Configuration: StreamConfigurationOptions and ArrowStreamConfigurationOptions with builder patterns matching the Java SDK
  • ProtoSchema: Unity Catalog → protobuf descriptor generation
  • Tests: 51 tests (30 unit + 21 integration with real gRPC mock server)
  • CI/CD: Workflows integrated into push.yml, release-dotnet.yml for NuGet publishing
  • Documentation: CLAUDE.md, README.md, CONTRIBUTING.md, CHANGELOG.md

WHY: .NET developers lacked a native SDK for high-throughput streaming ingestion into Databricks Delta tables. The C FFI (rust/ffi/) already supported C# as a target consumer. This implementation mirrors the Java SDK's API design while following .NET idioms (IDisposable, Task<T>, SafeHandle, delegates).

How is this tested?

  • 30 unit tests: Stream configuration options, builders, exceptions, enum values — all managed logic
  • 4 mock server self-tests: gRPC server starts, accepts connections, responds to create/ingest/batch, tracks records
  • 4 native smoke tests: DLL loads, builder_new/free, get_default_config, builder_build without crash
  • 17 integration tests (auto-skip without native lib): Stream creation, single/batch ingest, flush, waitForOffset, close, dispose, recovery, errors, configuration, concurrent ingestion
  • Manual validation: Full dotnet build && dotnet test passes on Windows (51/51 passing)

nalyd2 added 3 commits July 17, 2026 17:32
Initial implementation of the .NET SDK wrapping the Rust C FFI (rust/ffi/) via P/Invoke.

- JSON, Protocol Buffers, and Arrow Flight ingestion streams
- Fluent StreamBuilder API with typed sub-builders
- Thread-safe streams with ReaderWriterLockSlim
- IAsyncDisposable support (.NET 8+)
- HeadersProviderBridge for custom authentication callbacks
- ProtoSchema for Unity Catalog schema generation
- Integration tests with real gRPC mock server (zerobus_service.proto)
- 51 tests: 30 unit + 21 integration (4 self-test, 4 smoke, 17 end-to-end)
- CI/CD workflows integrated into push.yml and release-dotnet.yml
- Cross-platform NuGet package (win-x64, linux-x64, linux-arm64, osx-x64, osx-arm64)

Signed-off-by: Efrain Robles Gonzalez <efrain.robles@serviciosexternos.com.mx>
Set RecordType in native options struct (1=Proto, 2=Json) so stream
creation stops rejecting JSON/Proto streams with 'Record type is not
specified'. Also rework integration tests to avoid IAsyncLifetime,
which triggers a .NET 8.0.28 JIT bug causing InvalidProgramException
when combined with DllImport.

Signed-off-by: Efrain Robles Gonzalez <efrain.robles@serviciosexternos.com.mx>
Three discrepancies found by comparing C# hardcoded defaults against
zerobus_get_default_config() / zerobus_arrow_get_default_config():

1. CallbackMaxWaitTimeMs was null (wait forever), native default is 5000ms
2. MaxInflightBatches was 10000, native default is 1000
3. Arrow StreamPausedMaxWaitTimeMs was ulong (0), native expects int64_t
   with -1 meaning 'wait full server duration'

Also adds Defaults_MatchNativeConfig and ArrowDefaults_MatchNativeConfig
smoke tests to detect future drift.

Signed-off-by: Efrain Robles Gonzalez <efrain.robles@serviciosexternos.com.mx>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant