linliu-code opened a new pull request, #783:
URL: https://github.com/apache/hudi-rs/pull/783

   ## What this is
   
   Position **4 of 4** in a series porting work from Onehouse's `hudi-rs` fork 
onto upstream `main`. The series is linear and must land in order: **01 → 02 → 
03 → 04**.
   
   **Draft** — this cannot merge until #780 and any earlier position land.
   
   A PR to `apache/hudi-rs` must be based on a branch in this repository, so 
the series cannot be stacked on GitHub. This branch therefore carries the 
earlier positions' commits too, and the "Files changed" view is cumulative. 
**The work unique to this PR is 22 commits, `1c6e09c6..baa08e02`** — please 
review those.
   
   ## What it does
   
   Exports a `reader_v2` file-group read to the JVM as an **Arrow C stream**, 
plus `libhudi_jni.so` as the carrier.
   
   - `crates/jvm-ffi/` — builds the reader, performs the read, and hands back 
an `FFI_ArrowArrayStream`.
   - `crates/jni/` — the JNI entry points (`readFileGroupInto`, `version`).
   
   ## Memory and panic safety
   
   This is the part worth a careful pass, so here is what has already been 
checked:
   
   - **Every new `extern "C"` entry point is `catch_unwind`-guarded.** A Rust 
panic unwinding into the JVM is undefined behaviour; all three are wrapped and 
convert a panic into a thrown `NativeReaderException` or an error return.
   - **The Arrow C Data Interface contract holds.** `release` is always set, is 
reclaimed exactly once and is idempotent; `private_data` is deliberately leaked 
in `new` and reclaimed in `release`. `out_stream` is null-checked before the 
read and the `ptr::write` is the last statement, so the caller's struct is 
untouched on every error path.
   - **JNI local references are bounded** — each element read runs inside a 
`with_local_frame`, which pops on both the success and the error path. `throw` 
checks for a pending exception before raising a second.
   
   ## Known
   
   - **arrow-rs's own stream callbacks are unguarded.** `get_schema` / 
`get_next` / `get_last_error` / `release_stream` carry no `catch_unwind`. This 
is safe here only because the read is fully materialised into one `RecordBatch` 
*before* the stream is constructed, so all panic-capable decode happens inside 
the guarded entry point. That property is load-bearing; a lazy variant would 
need a per-`next()` guard.
   - **`crates/jni` has no tests in-repo** — it is `crate-type = ["cdylib"]`, 
so `cargo test` compiles it and runs nothing. It is exercised by a JVM consumer 
outside this repository. Inert by design rather than by accident, but worth 
knowing.
   - The reader context is built with several fields hardcoded, which suits the 
metadata table but is not obvious from the export's general-sounding name.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to