Skip to content

feat: Provide a low level Async Interface#150

Merged
mkaufmann merged 2 commits into
mainfrom
mkaufmann-async-low-level-interface
Feb 4, 2026
Merged

feat: Provide a low level Async Interface#150
mkaufmann merged 2 commits into
mainfrom
mkaufmann-async-low-level-interface

Conversation

@mkaufmann
Copy link
Copy Markdown
Member

@mkaufmann mkaufmann commented Jan 29, 2026

Why:
JDBC's synchronous interface is a poor fit for reactive frameworks
(RxJava, Vert.x, Project Reactor) and event-driven architectures.
Teams using these paradigms previously had to block threads or build
custom wrappers around our protocol. Note that this layer has less strong
API stability guarantees compared to the JDBC API as we might still need to
evolve it.

What:
- New async protocol layer under protocol/async/ with CompletionStage-
based iteration over query results, chunks, and query info
- Core abstractions: AsyncIterator, AsyncStreamObserver for gRPC
- Refactored sync iterators to extend SyncIteratorAdapter, reducing
duplication while preserving existing JDBC behavior
- Removed legacy BufferingStreamIterator/Observer in favor of new
async-first design

How:
- AsyncQueryResultIterator: manages full query lifecycle asynchronously
(execute → poll status → fetch chunks)
- AsyncExecuteQueryIterator: handles execute query stream with QueryInfo
tracking
- AsyncStreamObserverIterator: wraps gRPC ClientResponseObserver as
AsyncIterator with backpressure support
- SyncIteratorAdapter: bridges async iterators to blocking Iterator for
JDBC compatibility
- Usage examples demonstrate fully async consumption
patterns including error handling with QueryExceptionHandler that show how it should be used (see com.salesforce.datacloud.jdbc.examples.AsyncQueryResultIteratorTest)

@mkaufmann mkaufmann marked this pull request as draft January 29, 2026 15:53
…e cases

Why:
JDBC's synchronous interface is a poor fit for reactive frameworks
(RxJava, Vert.x, Project Reactor) and event-driven architectures.
Teams using these paradigms previously had to block threads or build
custom wrappers around our protocol. Note that this layer has less strong
API stability guarantees compared to the JDBC API as we might still need to
evolve it.

What:
- New async protocol layer under `protocol/async/` with CompletionStage-
  based iteration over query results, chunks, and query info
- Core abstractions: AsyncIterator<T>, AsyncStreamObserver for gRPC
- Refactored sync iterators to extend SyncIteratorAdapter, reducing
  duplication while preserving existing JDBC behavior
- Removed legacy BufferingStreamIterator/Observer in favor of new
  async-first design

How:
- AsyncQueryResultIterator: manages full query lifecycle asynchronously
  (execute → poll status → fetch chunks)
- AsyncExecuteQueryIterator: handles execute query stream with QueryInfo
  tracking
- AsyncStreamObserverIterator: wraps gRPC ClientResponseObserver as
  AsyncIterator with backpressure support
- SyncIteratorAdapter: bridges async iterators to blocking Iterator for
  JDBC compatibility
- Usage examples demonstrate fully async consumption
  patterns including error handling with QueryExceptionHandler that show how it should be used (see `com.salesforce.datacloud.jdbc.examples.AsyncQueryResultIteratorTest`)
@mkaufmann mkaufmann force-pushed the mkaufmann-async-low-level-interface branch from 35f8ea2 to 372902b Compare February 3, 2026 16:41
@mkaufmann mkaufmann marked this pull request as ready for review February 3, 2026 16:42
@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 3, 2026

Codecov Report

❌ Patch coverage is 82.84884% with 59 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.59%. Comparing base (6b2c170) to head (2a0c343).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
.../jdbc/protocol/async/core/SyncIteratorAdapter.java 61.53% 13 Missing and 2 partials ⚠️
.../jdbc/protocol/async/AsyncQueryResultIterator.java 84.21% 5 Missing and 4 partials ⚠️
...d/jdbc/protocol/async/AsyncChunkRangeIterator.java 66.66% 5 Missing and 3 partials ⚠️
.../jdbc/protocol/async/core/AsyncStreamObserver.java 86.88% 2 Missing and 6 partials ⚠️
...ud/jdbc/protocol/async/AsyncQueryInfoIterator.java 86.53% 2 Missing and 5 partials ⚠️
...jdbc/protocol/async/AsyncExecuteQueryIterator.java 80.64% 2 Missing and 4 partials ⚠️
.../jdbc/protocol/async/AsyncResultRangeIterator.java 86.66% 4 Missing ⚠️
...oud/jdbc/protocol/async/AsyncRowRangeIterator.java 91.30% 0 Missing and 2 partials ⚠️

❌ Your patch status has failed because the patch coverage (82.84%) is below the target coverage (90.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@             Coverage Diff              @@
##               main     #150      +/-   ##
============================================
- Coverage     82.74%   82.59%   -0.16%     
- Complexity     1301     1350      +49     
============================================
  Files           107      112       +5     
  Lines          3918     4062     +144     
  Branches        404      413       +9     
============================================
+ Hits           3242     3355     +113     
- Misses          493      515      +22     
- Partials        183      192       +9     
Components Coverage Δ
JDBC Core 83.72% <82.84%> (-0.25%) ⬇️
JDBC Main 40.69% <ø> (ø)
JDBC HTTP 91.09% <ø> (ø)
JDBC Utilities 66.07% <ø> (ø)
Spark Datasource ∅ <ø> (∅)
Files with missing lines Coverage Δ
...force/datacloud/jdbc/core/DataCloudConnection.java 58.45% <100.00%> (+0.29%) ⬆️
...atacloud/jdbc/protocol/AsyncQueryAccessHandle.java 100.00% <100.00%> (ø)
...ce/datacloud/jdbc/protocol/ChunkRangeIterator.java 71.42% <100.00%> (+3.68%) ⬆️
...rce/datacloud/jdbc/protocol/QueryInfoIterator.java 80.00% <100.00%> (-10.00%) ⬇️
...e/datacloud/jdbc/protocol/QueryResultIterator.java 100.00% <100.00%> (+17.64%) ⬆️
...e/datacloud/jdbc/protocol/QuerySchemaAccessor.java 90.00% <100.00%> (+0.52%) ⬆️
...orce/datacloud/jdbc/protocol/RowRangeIterator.java 66.66% <100.00%> (-19.55%) ⬇️
...otocol/async/core/AsyncStreamObserverIterator.java 100.00% <100.00%> (ø)
...oud/jdbc/protocol/async/AsyncRowRangeIterator.java 91.30% <91.30%> (ø)
.../jdbc/protocol/async/AsyncResultRangeIterator.java 86.66% <86.66%> (ø)
... and 6 more

Impacted file tree graph

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mkaufmann mkaufmann merged commit b1fba90 into main Feb 4, 2026
10 of 13 checks passed
@mkaufmann mkaufmann deleted the mkaufmann-async-low-level-interface branch February 4, 2026 16:35
KaviarasuSakthivadivel pushed a commit that referenced this pull request Feb 5, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.42.0](0.41.0...v0.42.0)
(2026-02-05)


### Features

* Add SSL/TLS Support to DataCloud JDBC Driver
([#89](#89))
([9123c1b](9123c1b))
* implement automated release pipeline using Release Please
([#139](#139))
([268eb2e](268eb2e))
* Provide a low level Async Interface
([#150](#150))
([b1fba90](b1fba90))
* Support PreparedStatement.getMetaData()
([#151](#151))
([52448d9](52448d9))


### Bug Fixes

* Breaking - Remove data loss for slow readers
([#142](#142))
([1ff41dc](1ff41dc))
* **ci:** remove explicit SNAPSHOT version from snapshot workflow
([#141](#141))
([b30c3fe](b30c3fe))
* **ci:** synchronize Release Please state to resolve empty change set
error ([#143](#143))
([8518b23](8518b23))
* **ci:** use simple release-type with extra-files for Gradle project
([#145](#145))
([5a8aac4](5a8aac4))


### Performance Improvements

* Optimize ResultSet column lookup with HashMap-based indexing
([#138](#138))
([b8c5eb9](b8c5eb9))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
KaviarasuSakthivadivel pushed a commit that referenced this pull request Feb 5, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.42.0](0.41.0...v0.42.0)
(2026-02-05)


### Features

* Add SSL/TLS Support to DataCloud JDBC Driver
([#89](#89))
([9123c1b](9123c1b))
* implement automated release pipeline using Release Please
([#139](#139))
([268eb2e](268eb2e))
* Provide a low level Async Interface
([#150](#150))
([b1fba90](b1fba90))
* Support PreparedStatement.getMetaData()
([#151](#151))
([52448d9](52448d9))


### Bug Fixes

* Breaking - Remove data loss for slow readers
([#142](#142))
([1ff41dc](1ff41dc))
* **ci:** remove explicit SNAPSHOT version from snapshot workflow
([#141](#141))
([b30c3fe](b30c3fe))
* **ci:** synchronize Release Please state to resolve empty change set
error ([#143](#143))
([8518b23](8518b23))
* **ci:** use simple release-type with extra-files for Gradle project
([#145](#145))
([5a8aac4](5a8aac4))
* Remove comments from JDBC driver version
([#153](#153))
([32f7216](32f7216))


### Performance Improvements

* Optimize ResultSet column lookup with HashMap-based indexing
([#138](#138))
([b8c5eb9](b8c5eb9))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.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.

3 participants