andygrove commented on code in PR #5722:
URL: https://github.com/apache/datafusion-comet/pull/5722#discussion_r3944263483


##########
spark/src/main/scala/org/apache/spark/sql/comet/execution/shuffle/NativeBatchDecoderIterator.scala:
##########
@@ -225,6 +233,7 @@ case class NativeBatchDecoderIterator(
 
         if (previous != null) release(previous.close())
         prefetched.filterNot(_ eq previous).foreach(pending => 
release(pending.close()))
+        if (decoderHandle != 0L) 
release(nativeLib.releaseRemoteShuffleDecoder(decoderHandle))

Review Comment:
   The P1 lifetime concern looks right to me. I reproduced the JVM half of it 
locally with a latch-based probe on this iterator and a mocked `Native`: 
`releaseRemoteShuffleDecoder` runs to completion while 
`decodeShuffleBlockWithValidation` is still inside the JNI call, so nothing in 
the iterator serializes the release against an active decode. 
`remoteDecoderHandle` is published from `fetchNext()` without the monitor that 
`close()` takes, and `decode_remote_shuffle_batch` reads `expected_types` after 
`read_ipc_compressed_validated` has already decompressed the block, so the 
borrow outlives the free in that ordering. The mirror-image ordering is a leak 
rather than a crash, since `close()` reads `0L` and the box is never freed.
   
   What I do not think is true is that this PR introduces the hazard. 
`CometExecIterator` has had the same shape for a long time, with a wider window 
on a much hotter path. It registers `close()` as a task completion listener at 
construction 
([`CometExecIterator.scala:189`](https://github.com/apache/datafusion-comet/blob/cedc3bd99ec4580226ffe77154a18fc7058a1547/spark/src/main/scala/org/apache/comet/CometExecIterator.scala#L189)),
 `close()` is `synchronized` and calls `nativeLib.releasePlan(plan)` 
([`:275`](https://github.com/apache/datafusion-comet/blob/cedc3bd99ec4580226ffe77154a18fc7058a1547/spark/src/main/scala/org/apache/comet/CometExecIterator.scala#L275)
 and 
[`:305`](https://github.com/apache/datafusion-comet/blob/cedc3bd99ec4580226ffe77154a18fc7058a1547/spark/src/main/scala/org/apache/comet/CometExecIterator.scala#L305)),
 and `getNextBatch` calls `nativeLib.executePlan(..., plan, ...)` outside that 
monitor ([`:205`](https://github.com/apache/datafusion-comet/blob/cedc3bd99ec45
 
80226ffe77154a18fc7058a1547/spark/src/main/scala/org/apache/comet/CometExecIterator.scala#L205)).
 On the native side `releasePlan` is a `Box::from_raw` drop of the context 
([`jni_api.rs:1051`](https://github.com/apache/datafusion-comet/blob/cedc3bd99ec4580226ffe77154a18fc7058a1547/native/core/src/execution/jni_api.rs#L1051))
 while `executePlan` holds `get_execution_context(exec_context)`, an unbounded 
`&'a mut ExecutionContext` derived from the raw handle, for the duration of an 
entire plan execution 
([`jni_api.rs:848`](https://github.com/apache/datafusion-comet/blob/cedc3bd99ec4580226ffe77154a18fc7058a1547/native/core/src/execution/jni_api.rs#L848)).
 So if the threaded Python consumer plus an interrupted cleanup wait reaches 
the shuffle decoder, it already reaches every Comet native plan today.
   
   Given that, I would rather not hold this PR for it. Could we file one issue 
covering JVM-owned native handle lifetime for both `NativeBatchDecoderIterator` 
and `CometExecIterator`, and fix them the same way? Fixing only the new handle 
here would leave the wider window untouched and leave us with two different 
ownership conventions for the same problem.
   
   For what it is worth, the minimal fix for this iterator looks like taking 
the monitor around just the `nativeUtil.getNextBatch` call and leaving 
`readNextBlock()` outside it, so `in.close()` can still unblock a transport 
read. Decoding one block is bounded work, so cleanup cannot hang waiting on the 
monitor. Whatever we settle on should apply to `releasePlan` as well.
   



-- 
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]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to