QuakeWang opened a new issue, #2214:
URL: https://github.com/apache/datafusion-ballista/issues/2214

   # StaticExecutionGraph drops stages when plan transformations fail
   
   **Describe the bug**
   
   Several `StaticExecutionGraph` state transitions remove a stage from 
`self.stages` before performing a fallible physical-plan transformation.
   
   The affected transitions are:
   
   - `resolve_stage`
   - `rollback_running_stage`
   - `rollback_resolved_stage`
   
   For example, `resolve_stage` currently follows this pattern:
   
   ```rust
   if let Some(ExecutionStage::UnResolved(stage)) =
       self.stages.remove(&stage_id)
   {
       self.stages.insert(
           stage_id,
           ExecutionStage::Resolved(
               stage.to_resolved(self.session_config.options())?,
           ),
       );
   }
   ```
   
   The stage is removed before `to_resolved` is evaluated. If the 
transformation returns an error, `?` returns from the transition before 
`insert` is called, so the original stage is dropped and the stage ID is left 
absent from the execution graph.
   
   The two rollback transitions have the same ordering around 
`to_unresolved(...)`.
   
   These transformations can fail while replacing shuffle nodes, rebuilding 
physical-plan nodes, constructing shuffle readers, or applying physical 
optimizer rules.
   
   The error is propagated through the scheduler, but callers operate directly 
on the active execution graph and do not restore a previous snapshot. A failed 
transition can therefore mutate the graph even though no replacement stage was 
successfully produced.
   
   **To Reproduce**
   
   A deterministic unit-level reproduction can use a test execution-plan node 
whose `with_new_children` implementation returns an error when the shuffle 
child is rewritten.
   
   For each affected transition:
   
   1. Construct a `StaticExecutionGraph` containing a stage in the required 
initial state.
   2. Record the stage count and the stage's state.
   3. Invoke the transition with a plan transformation that returns an error.
   4. Verify that the transition returns `Err`.
   5. Inspect `graph.stages()` for the original stage ID.
   
   With the current implementation, the stage ID is no longer present because 
the stage was removed before the transformation failed.
   
   The same outcome follows directly from the current control flow: `remove` 
completes before the fallible transformation is evaluated, while `insert` is 
skipped by the early return.
   
   **Expected behavior**
   
   Stage transitions should be failure-atomic.
   
   If a physical-plan transformation fails:
   
   - the transition should return the original error;
   - the original stage should remain in the execution graph;
   - its state, plan, task metadata, and attempt information should remain as 
they were at the start of the transition; and
   - no replacement stage should be committed.
   
   A successful transformation should retain the existing transition behavior.
   
   **Additional context**
   
   This issue was found by inspecting the transition control flow. The exact 
user-visible outcome depends on which physical-plan transformation fails, so 
this report does not claim a specific production failure mode or occurrence 
frequency.
   
   The proposed scope is limited to the three `StaticExecutionGraph` 
transitions in `ballista/scheduler/src/state/execution_graph.rs`:
   
   - compute the replacement stage before committing it to `self.stages`;
   - commit the replacement only after the fallible transformation succeeds; and
   - add regression coverage for the error path of each transition.
   
   This should not require changes to public APIs, scheduling policy, retry 
policy, stage-attempt behavior, or stage dependency semantics. It also does not 
propose making the surrounding task-update or executor-loss operations fully 
transactional.
   


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