andygrove opened a new pull request, #2032:
URL: https://github.com/apache/datafusion-ballista/pull/2032

   > **Status: WIP / experimental.** Opened as a draft for early feedback. This 
is the first of two stacked PRs; the second builds an opt-in OOM guard on top 
of it.
   
   # Which issue does this PR close?
   
   Relates to #2031. It does not close it — this PR only fixes the failure 
*classification*; the memory accounting itself is the follow-up.
   
   # Rationale for this change
   
   A task that exhausts its memory budget currently fails the entire job on the 
first occurrence. `From<BallistaError> for FailedTask` maps everything that is 
not an IO error to `FailedReason::ExecutionError`, and 
`ExecutionGraph::update_task_status` fails the stage outright on that reason 
with no retry.
   
   Memory exhaustion is often transient. The retried task may land on a 
less-loaded executor, or run once its peers on the same executor have drained — 
the same reasoning Spark uses. The retry is bounded by `--task-max-failures` 
(default 4), so a task that is simply too large still fails the job, but with a 
clear message rather than immediately.
   
   While tracing this I found the classification was also *unreachable* for a 
large class of stages, which is the second half of the change:
   
   `ShuffleWriterExec`, on the `shuffle_output_partitioning == None` branch, 
flattened the stream error with `map_err(|e| 
DataFusionError::Execution(format!("{e:?}")))` before it reached the 
classifier. That destroys the error type, so `find_root()` sees `Execution` and 
the task is classified non-retriable. Per `planner.rs`, the `None`-partitioned 
stages are the final stage, the **broadcast-join build side**, the 
`CoalescePartitionsExec` input stage, and the `SortPreservingMergeExec` input 
stage — i.e. several of the stages most likely to exhaust memory in the first 
place. The hash-partitioned branch and the sort-shuffle writer already 
propagated the error unchanged.
   
   # What changes are included in this PR?
   
   - `ballista.proto`: a new `ResourcesExhausted` message and a 
`resources_exhausted` arm (field 10) on the `FailedTask.failed_reason` oneof.
   - `error.rs`: a new arm in `From<BallistaError> for FailedTask` setting 
`retryable: true, count_to_failures: true`. It matches through 
`DataFusionError::find_root()`, because DataFusion routinely wraps errors in 
`Context`, and in `Shared` when propagating one stream error to several output 
partitions (`RepartitionExec`) — a bare match on the outer error would miss 
most real cases. There are tests for the bare, `Context`-wrapped, and 
`Shared`-wrapped forms.
   - `shuffle_writer.rs`: preserve the `DataFusionError` on the unpartitioned 
write path instead of formatting it into an `Execution` error.
   - `handlers.rs`: a new arm in `failed_reason()`, which is an exhaustive 
match. Kept exhaustive deliberately — it is display-only, and it is a useful 
tripwire for the next `FailedReason` added.
   
   No scheduler logic change is required: `update_task_status`'s existing 
`Some(_)` arm already retries any reason that is not `ExecutionError` or 
`FetchPartitionError` when `retryable && count_to_failures`. Verified this 
holds on both the static and the AQE planner paths.
   
   # Are there any user-facing changes?
   
   Yes, and reviewers should weigh this explicitly: **this changes 
default-build behaviour.** A `ResourcesExhausted` — which a bounded 
`FairSpillPool` can raise today — is now retried up to `--task-max-failures` 
times instead of failing the job immediately. For a *transient* spike that is 
the point. For a *deterministic* one, the job now performs the same work up to 
4 times before surfacing the identical failure. That trade-off is the main 
thing I would like feedback on; if it is unwelcome, the classification could be 
gated behind the follow-up PR's cargo feature instead.
   
   The proto change adds a new oneof field; it does not alter existing fields.


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