[SPARK-59674][CORE] Fix Comparison method violates its general contract in FIFOSchedulingAlgorithm - #58933
[SPARK-59674][CORE] Fix Comparison method violates its general contract in FIFOSchedulingAlgorithm#58933wangyum wants to merge 1 commit into
Conversation
|
cc @cloud-fan |
cloud-fan
left a comment
There was a problem hiding this comment.
Review summary
The overflow-safe implementation is sound and preserves the intended FIFO ordering. The remaining issue is durable regression coverage: the current Spark tests do not distinguish either Integer.compare change from the previous subtraction, so both boundary paths should be covered in-repo. This is a non-blocking test gap, not a production-code correctness issue.
Findings
1 total: 0 P0, 0 P1, 1 P2, 0 P3.
Non-blocking (P2)
- Add regression coverage for both overflow comparisons —
core/src/main/scala/org/apache/spark/scheduler/SchedulingAlgorithm.scala:31— see inline.
| val priority1 = s1.priority | ||
| val priority2 = s2.priority | ||
| var res = math.signum(priority1 - priority2) | ||
| var res = Integer.compare(s1.priority, s2.priority) |
There was a problem hiding this comment.
Non-blocking (P2): Please add an in-repo regression test that fails against the old subtraction for both changed comparisons: priorities spanning Int.MinValue and Int.MaxValue, and equal-priority schedulables whose stage IDs span the same bounds. PoolSuite currently fixes priority at 0 and uses only small stage IDs, so it passes with the old comparator and would not catch a reintroduction of this scheduler-stalling failure.
|
Thanks for the ping. I reviewed the current patch and will post the review outcome here. |
What changes were proposed in this pull request?
FIFOSchedulingAlgorithm.comparator(used byPool.getSortedTaskSetQueueto orderTaskSetManagers/Pools in FIFO scheduling mode) comparedpriorityandstageIdusing:math.signum(priority1 - priority2)This subtraction can silently overflow when the two
Intvalues are far apart (e.g. spanInt.MinValue..Int.MaxValue), which flips the sign of the result and violates theComparatorcontract (anti-symmetry/transitivity).This PR replaces the subtraction-based
signumcomparisons withInteger.compare, which compares the two values directly and cannot overflow:Why are the changes needed?
A broken comparator contract makes
java.util.TimSortdetect the inconsistency during the merge phase and throw, which surfaces as a driver-side failure when offering resources to executors:Once this is thrown from
resourceOffers, resource offers stop being processed correctly, which can stall task scheduling entirely.Integer.compareperforms a purely logical comparison and does not have this overflow failure mode, so it satisfies theComparatorcontract for any pair ofIntvalues.Does this PR introduce any user-facing change?
No.
How was this patch tested?
Manually verified both the failure and the fix with a minimal reproduction outside the Spark test suite:
Was this patch authored or co-authored using generative AI tooling?
Generated-by: Claude Sonnet 5 (Anthropic)