fix(kubernetes): fail recovery when executor status is unknown - #1599
Open
mengdehong wants to merge 1 commit into
Open
fix(kubernetes): fail recovery when executor status is unknown#1599mengdehong wants to merge 1 commit into
mengdehong wants to merge 1 commit into
Conversation
mengdehong
requested review from
Generalwin,
Spground and
fengcone
as code owners
August 23, 2026 05:36
mengdehong
requested review from
Pangjiping,
hittyt,
kevinlynx and
ninan-nn
as code owners
August 23, 2026 05:36
Contributor
There was a problem hiding this comment.
Pull request overview
This PR hardens the Kubernetes scheduler’s recovery and status polling behavior so “unknown” executor states (due to unreachable executors or partial collection) no longer get silently treated as “no task running,” preventing incorrect freeing of task nodes after restart.
Changes:
- Update
taskStatusCollector.Collect()to return(map[string]*api.Task, error)and explicitly differentiate “confirmed empty” (ip -> nil) from “query failed” (missing key + non-nil error). - Make recovery retryable and atomic by removing
sync.Once, propagating collection errors, and validating completeness before mutating anytaskNode. - Preserve last-known task
Status/ state during runtime polling when collection fails (avoid overwriting withnilon errors).
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| kubernetes/internal/scheduler/status_collector.go | Collector now returns (map, error) and records explicit nil entries vs missing-on-error. |
| kubernetes/internal/scheduler/status_collector_test.go | New unit tests covering empty-vs-error distinction and success path. |
| kubernetes/internal/scheduler/status_collector_mock.go | Regenerated gomock to match new Collect() signature. |
| kubernetes/internal/scheduler/recovery.go | Recovery now propagates errors and validates complete collection before updating nodes. |
| kubernetes/internal/scheduler/recovery_test.go | Adds tests for atomicity, error propagation, and incomplete-collection rejection. |
| kubernetes/internal/scheduler/default_scheduler.go | Polling now preserves last-known status/state on collection error and skips missing entries. |
| kubernetes/internal/scheduler/default_scheduler_test.go | Updates mocks for new signature and adds polling error-preservation test. |
Files not reviewed (1)
- kubernetes/internal/scheduler/status_collector_mock.go: Generated file
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
mengdehong
force-pushed
the
fix/kubernetes-scheduler-recovery
branch
from
August 23, 2026 08:03
6759e32 to
25fcd1b
Compare
Propagate task-executor status collection errors so scheduler recovery can be retried instead of treating unknown pods as free. Preserve last-known status during polling failures and reject incomplete recovery results before mutating task bindings.
mengdehong
force-pushed
the
fix/kubernetes-scheduler-recovery
branch
from
August 23, 2026 12:31
25fcd1b to
ac4da52
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Scheduler recovery silently treated unknown pod status as "no task running", which could leave the scheduler in an inconsistent state after restart when task-executors were temporarily unreachable.
What is changing:
taskStatusCollector.Collect()now returns(map[string]*api.Task, error)so recovery can distinguish "executor confirmed empty" (ret[ip] = nil) from "query failed" (missing entry + error).recover()dropssync.Onceand propagates errors, allowing recovery to be retried after a failed attempt.recoverTaskNodesStatus()validates that every pod IP has a corresponding result before mutating anytaskNode, ensuring recovery either completes fully or leaves the existing state unchanged.Runtime polling behavior remains unchanged.
Why:
Previously, when an executor was unreachable during recovery:
Collect().taskNodecould be incorrectly treated as free.sync.Onceprevented recovery from being retried.Recovery should be atomic: either fully succeed or leave scheduler state unchanged for a later retry.
Testing
Collect()signature.go test ./internal/scheduler/....Breaking Changes
taskStatusCollector.Collect()now returns(map[string]*api.Task, error). The interface is contained withinkubernetes/internal/schedulerand does not affect public APIs, SDKs, CRDs, or configuration.Checklist