[Feature] C++ client: provide async/callback API for write result instead of blocking Wait()
- Dominant language
- Java
- Stars
- 2.1k
- Forks
- 625
- Avg merge
- 3d 14h
- Merged PRs (30d)
- 97
Description
### Search before asking
- [x] I searched in the [issues](https://github.com/apache/fluss/issues) and found nothing similar.
### Motivation
### Background
In the Java client, `AppendWriter::append` returns a `CompletableFuture`. Users can register success/failure callbacks directly on the future, e.g.:
```java
appendWriter.append(row)
.thenAccept(result -> { /* success */ })
.exceptionally(ex -> { /* failure */ return null; });
```
The Rust core client takes a different approach. AppendWriter::append is not async; it enqueues the write and returns a WriteResultFuture immediately. Rust users handle the result with .await / tokio::spawn / match, without registering callbacks on the future:
```rust
// .await suspends the current async task but does NOT block the OS thread
match fut.await {
Ok(_) => ...,
Err(e) => ...,
}
// Or offload the result handling to a background task
tokio::spawn(async move {
match fut.await {
Ok(_) => callback_ok(),
Err(e) => callback_err(e),
}
```
This works because Rust's .await yields the current task back to the tokio runtime, allowing other tasks to run on the same thread. It blocks only the async control flow, not the underlying thread.
### Current C++ binding behavior
However, the C++ binding wraps this future with a synchronous API. The binding uses a static Tokio runtime and blocks the calling thread on the future:
* Static runtime definition:
https://github.com/apache/fluss/blob/main/fluss-rust/bindings/cpp/src/lib.rs#L36-L41
* AppendWriter::flush blocks via RUNTIME.block_on:
https://github.com/apache/fluss/blob/main/fluss-rust/bindings/cpp/src/lib.rs#L2204-L2210
* WriteResult::wait blocks via RUNTIME.block_on:
https://github.com/apache/fluss/blob/main/fluss-rust/bindings/cpp/src/lib.rs#L2222-L2233
As a result, C++ users must explicitly call WriteResult::Wait() (or AppendWriter::Flush()) and the calling thread is blocked until the server acknowledges the write.
### Solution
Is there a plan to expose an asynchronous method for C++ users? For example:
Return a std::future from Append / AppendArrowBatch, so users can decide when to wait.
Provide a callback-based overload such as Append(row, callback) where the callback is invoked on completion.
Keep the current Wait() API but additionally expose a non-blocking IsReady() / TryWait() to poll the result.
### Anything else?
_No response_
### Willingness to contribute
- [ ] I'm willing to submit a PR!
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reading the static runtime definition and the AppendWriter::flush and WriteResult::wait implementations in fluss-rust/bindings/cpp/src/lib.rs at the cited lines. Compare the existing C++ binding surface with the proposed future, callback, or polling options; done requires a decided non-blocking API contract and matching completion behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, rust
- Domain
- api
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100