jerrypeng commented on code in PR #59523:
URL: https://github.com/apache/spark/pull/59523#discussion_r4406405959


##########
core/src/main/scala/org/apache/spark/scheduler/DAGScheduler.scala:
##########
@@ -1516,6 +1515,29 @@ private[spark] class DAGScheduler(
     checkPipelinedStageCreation(finalRDD, partitions, jobId)
   }
 
+  /** Reject persistence that could bypass a native pipelined shuffle reader. 
*/
+  private def checkPipelinedCacheSupported(finalRDD: RDD[_]): Unit = {
+    val persisted = new HashSet[RDD[_]]
+    traverseRDDGraph(finalRDD) { (rdd, enqueue) =>
+      if (rdd.getStorageLevel != StorageLevel.NONE ||
+          
rdd.checkpointData.exists(_.isInstanceOf[LocalRDDCheckpointData[_]])) {
+        persisted += rdd
+      }
+      rdd.dependencies.foreach(dep => enqueue(dep.rdd))
+    }
+    // Cache locations cannot establish a stable cut: eviction can revive an 
upstream producer,
+    // and a partial cache hit skips a reader whose producer still needs its 
termination ACK.
+    // Check storage intent instead, including pending local checkpoints and 
narrow descendants.
+    val visited = new HashSet[RDD[_]]
+    if (persisted.exists(rdd => rddChainReadsPipelinedShuffle(rdd, visited))) {

Review Comment:
   Agreed. `AttachDistributedSequenceExec` creates its temporary cache directly 
through RDD
   `persist()` or `localCheckpoint()`, so it bypasses `CacheManager`'s 
protection. I added
   `AttachDistributedSequenceExec(cache = true)` to the shared 
`isUnsupportedConsumer` predicate.
   Both the AQE and non-AQE rules now retain regular input shuffles, allowing 
the indexing job
   to execute without hitting the new scheduler rejection.
   
   Using the consumer check preserves pipelining for `cache = false` and for 
cached indexing
   on shuffle-free input that feeds a downstream shuffle. The regression tests 
execute the
   indexing operator with AQE on/off, default and memory caching, local 
checkpointing, and
   `NONE`, including a shuffle above the indexing operator. They verify all 
4,000 input IDs
   and consecutive index values, and cover both supported pipelined cases.
   
   The restriction deliberately follows the operator's `cache` flag, so 
eligibility does not
   depend on reading mutable pandas configuration during planning. It 
conservatively retains
   regular input shuffles for `cache = true` even with `NONE` or a single input 
partition,
   where execution would not persist. The existing all-or-nothing rules can 
also keep other
   exchanges in the plan regular. This is a compatibility fix; I have not 
benchmarked its
   performance impact.



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