Skip to content

Feat/dotnet arrow streams - #541

Open
nalyd2 wants to merge 4 commits into
databricks:mainfrom
nalyd2:feat/dotnet-arrow-streams
Open

Feat/dotnet arrow streams#541
nalyd2 wants to merge 4 commits into
databricks:mainfrom
nalyd2:feat/dotnet-arrow-streams

Conversation

@nalyd2

@nalyd2 nalyd2 commented Jul 20, 2026

Copy link
Copy Markdown

What changes are proposed in this pull request?

This PR adds Arrow Flight ingestion stream support, ProtoSchema, a fluent StreamBuilder API, async Arrow operations, and a MockFlightServer for integration testing to the .NET SDK.

Major changes:

Arrow Flight streams (ZerobusArrowStream)

  • Thread-safe Arrow Flight ingestion with IngestBatch(byte[]), Flush(), Close(), GetUnackedBatches()
  • Async variants: IngestBatchAsync, WaitForOffsetAsync, FlushAsync, CloseAsync
  • ArrowStreamConfigurationOptions record with IPC compression (None, LZ4_FRAME, ZSTD)
  • ArrowBatchInfo record for unacknowledged batch recovery
  • IPCCompressionType enum

ProtoSchema

  • FromUnityCatalogJson(string) — generates protobuf schemas from Unity Catalog API responses
  • GetDescriptorBytes() — returns compiled FileDescriptorProto bytes for stream creation
  • EncodeJson(string) — converts JSON records to protobuf bytes matching the table schema
  • Example showing dual auth paths (Databricks REST API + inline JSON fallback)

Fluent StreamBuilder API

  • sdk.StreamBuilder().Table(...).OAuth(...).Json().Build()
  • Sub-builders: JsonStreamBuilder, ProtoStreamBuilder, ArrowStreamBuilder
  • Coexists with direct factory methods (CreateJsonStream, CreateProtoStream, CreateArrowStream)

MockFlightServer (integration tests)

  • Implements Arrow Flight DoPut protocol using Apache.Arrow.Flight.AspNetCore
  • Handles stream-ready signal (ack_up_to_offset=-1) and per-batch acknowledgements
  • Registered in MockServerFixture alongside the existing JSON/Proto mock
  • All 18 Arrow tests now run against the local mock server (previously 10 were skipped)

Why: These features enable high-performance Arrow columnar ingestion into Databricks Delta tables, runtime protobuf schema generation from Unity Catalog (no local .proto compilation needed), and a discoverable fluent API for stream creation. The MockFlightServer unblocks Arrow integration testing without requiring a real Databricks endpoint.

Note: This work continues from the discussion in #532, which was superseded by #536. The features here (Arrow Flight streams, ProtoSchema, StreamBuilder, MockFlightServer) are additional contributions on top of the merged codebase.

How is this tested?

140 tests passing (0 skipped, 0 failed):

Suite Framework Tests
Unit tests (Zerobus.Tests) NUnit 70 ✅
Integration tests (Zerobus.IntegrationTests) NUnit + mock gRPC 70 ✅

New tests added (43 total):

  • StreamBuilderTests.cs — 13 tests (fluent API, null checks, return types)
  • ArrowStreamConfigurationOptionsTests.cs — 6 tests (defaults, with expressions, IPC enum)
  • ArrowBatchInfoTests.cs — 2 tests (record equality)
  • ProtoSchemaTests.cs — 4 tests (argument validation, API surface)
  • ArrowIntegrationTests.cs — 18 tests (create, ingest, flush, close, async, multiple batches, mock server assertions)

Test infrastructure:

  • MockZerobusServer — gRPC mock for JSON/Proto (existing)
  • MockFlightServer — gRPC mock for Arrow Flight DoPut (new, this PR)
  • Tests run against both net8.0 and net10.0

nalyd2 added 4 commits July 20, 2026 16:09
Add Arrow Flight ingestion streams (ZerobusArrowStream) with IPC
compression support, thread-safe lifecycle, and OAuth/headers-provider
authentication. Includes ArrowStreamConfigurationOptions record.

Add ProtoSchema class for generating protobuf schemas from Unity
Catalog table metadata, including descriptor byte extraction and
JSON-to-protobuf encoding.

Signed-off-by: nalyd2 <jazer_252_@hotmail.com>
Add fluent StreamBuilder API as an alternative to ZerobusSdk factory
methods. Supports chaining .Table(), .OAuth(), .MaxInflightRequests(),
.Recovery() etc. with typed sub-builders for JSON, Proto, and Arrow.

Add async operations to ZerobusArrowStream: IngestBatchAsync,
WaitForOffsetAsync, FlushAsync, CloseAsync, GetUnackedBatchesAsync.

Add integration tests for Arrow streams and StreamBuilder validation.
Includes 25 new unit tests and 15 integration tests.

Signed-off-by: nalyd2 <jazer_252_@hotmail.com>
Add ProtoSchema example with dual path:
- Option A: fetch Unity Catalog table metadata via Databricks REST API
  (requires DATABRICKS_TOKEN env var)
- Option B: inline JSON fallback for development/CI

Full workflow: UC JSON → ProtoSchema → descriptor → proto stream
→ EncodeJson (JSON to protobuf conversion) → ingest → flush.

Update README: StreamBuilder and factory methods in Quick Start,
Arrow Flight API reference, ProtoSchema section,
ArrowStreamConfigurationOptions table, updated project structure.

Signed-off-by: nalyd2 <jazer_252_@hotmail.com>
Implement MockFlightServer using Apache.Arrow.Flight.AspNetCore that
extends FlightServer and handles the Arrow Flight DoPut protocol.
Enables all 18 Arrow integration tests to run against the local mock
server instead of skipping.

- Add MockFlightServer implementing FlightServer.DoPut with:
  - Stream-ready signal (ack_up_to_offset=-1) after schema
  - Per-batch acknowledgements with offset_id from app_metadata
  - Graceful handling of client disconnect (no-data tests)
- Register MockFlightServer in MockServerFixture via AddFlightServer<T>
  and MapFlightEndpoint, serving on the same port as MockZerobusServer
- Add Apache.Arrow.Flight and Apache.Arrow.Flight.AspNetCore v19.0.0
- Fix JSON serialization to use snake_case (Rust SDK serde expects
  ack_up_to_offset / ack_up_to_records)
- Replace raw byte arrays with valid Arrow IPC batch bytes in tests
- Add assertions against ArrowFlightServer state (BatchesReceived,
  MaxOffsetSeen)
- Remove all Assert.Ignore skip logic -- all 18 Arrow tests now pass

Signed-off-by: nalyd2 <jazer_252_@hotmail.com>
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