Skip to content

fix(scheduler): reset unlaunched tasks when executor metadata is missing - #2698

Open
ump45nose wants to merge 4 commits into
apache:mainfrom
ump45nose:fix/2691-reset-unlaunched-on-metadata-miss
Open

ump45nose wants to merge 4 commits into
apache:mainfrom
ump45nose:fix/2691-reset-unlaunched-on-metadata-miss

Conversation

@ump45nose

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Closes #2691.

Rationale for this change

#2689 refunds vcore reservations when launch_tasks cannot get executor metadata, but the tasks in that batch were already recorded as Running at bind time. They were never launched, never reported, and never reset, so the job hung until the executor was lost. Because the refund sets if_revive, a repeated miss also binds more partitions onto the same stranded path.

pop_next_task's contract already says a bound-but-unlaunched task must have its status reset so it can be scheduled elsewhere; this fills that gap for the metadata-miss branch.

What changes are included in this PR?

  • Add ExecutionGraph::reset_unlaunched_task (static + AQE) that returns a still-Running task_info slot to pending via reset_task_info.
  • On the metadata-lookup failure path in SchedulerState::launch_tasks, call TaskManager::reset_unlaunched_tasks before refunding reservations.
  • Extend launch_tasks_refunds_vcores_when_executor_metadata_missing to assert pending task count is restored after the miss.

Are there any user-facing changes?

No.


This PR was prepared with AI assistance; I reviewed the change and ran the checks above.

Bound tasks are recorded as Running at bind time. When launch_tasks
cannot get executor metadata, apache#2689 refunds the vcore reservations but
left those tasks stranded as Running with no status updates, so the job
hung until the executor was lost.

Reset each unlaunched task back to pending (as pop_next_task's contract
requires) before refunding vcores, and assert pending work is restored
in the metadata-miss test.

Closes apache#2691.
/// `Running` with no status updates ever arriving. See #2691.
///
/// Returns `true` when the task was still `Running` and was reset.
fn reset_unlaunched_task(&mut self, key: &TaskKey) -> bool;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since ExecutionGraph is a public trait, adding a required method breaks anyone implementing it outside the repo. Could we give it a default body that returns false? That matches the "nothing was reset" meaning in the doc, and both built-in graphs override it anyway, so behaviour here doesn't change. Otherwise it'll need the api-change label and an upgrade-guide note.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in cdf608d: reset_unlaunched_task now has a default body that returns false, so out-of-tree ExecutionGraph implementations keep compiling. StaticExecutionGraph and AdaptiveExecutionGraph both override it. Sorry for not replying here earlier.

I also merged current main in 9b14201 to clear the conflict in state/aqe/mod.rs (an import list). cargo clippy -p ballista-scheduler --all-targets -D warnings is clean, and cargo test -p ballista-scheduler --lib passes (627 passed, 2 ignored).

(AI-assisted reply.)

ump45nose and others added 3 commits October 31, 2026 23:30
ExecutionGraph is a public trait; a required method would break
out-of-tree implementations. Default to resetting nothing.

Signed-off-by: Vincent <[email protected]>
Resolve the trait through the parent module so moving the plan-rewrite
test helper and its imports does not break the merged test build.

AI-assisted. Static name-resolution and focused diff checks performed;
Rust compilation and rustfmt were not run locally (toolchain unavailable).
The merged build is left to GitHub Actions.
…unched-on-metadata-miss

Resolve the aqe/mod.rs import conflict (keep TaskKey alongside main's
ExecutorEndpoint) and drop the super::ExecutionPlan qualification in the
cache reader test helper, which main's test-module imports make
unnecessary.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tasks bound in launch_tasks are orphaned when the executor metadata lookup fails

2 participants