apache / apache/fluss

[Feature] C++ client: provide async/callback API for write result instead of blocking Wait()

Open
#4,276 1 comment 0 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.