villebro opened a new pull request, #2202:
URL: https://github.com/apache/datafusion-ballista/pull/2202
<!--
We generally require a GitHub issue to be filed for all bug fixes and
enhancements and this helps us generate change logs for our releases. You can
link an issue to this PR using the GitHub syntax. For example `Closes #123`
indicates that this PR will close issue #123.
-->
Closes #2027.
# Rationale for this change
<!--
Why are you proposing this change? If this is already explained clearly in
the issue then this section is not needed.
Explaining clearly why changes are proposed helps reviewers understand your
changes and offer better suggestions for fixes.
-->
Issue #2027 describes scheduler recovery failing after an executor dies
after producing shuffle output. The fetch path starts with the useful
structured error:
```text
FetchFailed { executor_id, map_stage_id, map_partition_id, message }
```
Those fields are exactly what the scheduler needs in order to invalidate the
lost shuffle output and resubmit the producing map stage.
The problem is that the error crosses DataFusion's execution stream inside
wrapper errors:
```text
DataFusionError::ArrowError(
ArrowError::ExternalError(
FetchFailed { ... }
)
)
```
Before this change, the executor wrapped that whole DataFusion error inside
`BallistaError::DataFusionError` before building `FailedTask`. The classifier
then only saw the outer wrapper, not the inner `FetchFailed`, and reported a
non-retryable `ExecutionError`. The scheduler recovery path is keyed on
`FetchPartitionError`, so it never ran.
The exact location hints in the issue reflect the codebase when it was
written; after later changes, those same lines point at test code on this
branch. The production type loss fixed here is the wrapping path described
above.
# What changes are included in this PR?
<!--
There is no need to duplicate the description in the issue here but it is
sometimes worth providing a summary of the individual changes in this PR.
-->
The fix has two parts.
First, the executor now uses the existing `BallistaError` conversion when a
query stage fails. For the common shuffle-fetch shape, that means the
DataFusion/Arrow wrapper can be converted back into the original `FetchFailed`
instead of being carried forward as an opaque DataFusion error.
Second, task-failure classification now looks inside the DataFusion/Arrow
wrapper stack before falling back to a generic execution error. If it finds a
`FetchFailed`, it builds the `FetchPartitionError` that scheduler recovery is
already expecting.
This is targeted at the known shuffle fetch path, where `FetchFailed`
travels through `ArrowError::ExternalError`. A direct
`DataFusionError::External(Box<BallistaError>)` fetch path is not known to be
produced here, so that is outside this change. Other scheduler failure reasons
are set elsewhere, and IO retryability keeps using DataFusion's root-error
lookup.
The tests cover the executor-boundary conversion, the old bare `FetchFailed`
case, wrapped fetch failures, defensive DataFusion `Shared`/`Context` wrapping,
and a non-fetch negative case. The existing scheduler fetch-failure recovery
test now builds its failed task through the real classifier, so it exercises
classification and scheduler recovery together without adding another similar
graph-level scenario.
Validation:
- `cargo test -p ballista-core error::tests`
- `cargo test -p ballista-scheduler test_normal_fetch_failure`
- Manual Ballista smoke test: ran Ballista with these changes and did not
see issues. A faithful executor-death shuffle-fetch repro was not produced
locally; the chaos harness in #2026 should make this easier once it lands. The
`executor_killed_mid_stage_is_recovered` chaos scenario should be added as an
end-to-end regression test once that harness is available.
# Are there any user-facing changes?
<!--
If there are user-facing changes then we may require documentation to be
updated before approving the PR.
-->
No API or documentation changes.
Behavior change: a shuffle fetch failure that was previously reported as a
non-retryable execution error is now classified as a fetch-partition error, so
the scheduler resubmits the map stage instead of failing the job.
No breaking changes to public APIs.
<!--
If there are any breaking changes to public APIs, please add the `api
change` label.
-->
--
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]