fix(controller): track executor state with LRU eviction instead of id-based skip#2977
fix(controller): track executor state with LRU eviction instead of id-based skip#2977shashankch292 wants to merge 1 commit into
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
🎉 Welcome to the Kubeflow Spark Operator! 🎉 Thanks for opening your first PR! We're happy to have you as part of our community 🚀 Here's what happens next:
Join the community:
Feel free to ask questions in the comments if you need any help or clarification! |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds bounded tracking for executor states by enforcing MaxTrackedExecutorPerApp after reconciliation, and introduces a pod-name-based executor ID parser as a fallback when pod labels are unavailable.
Changes:
- Added
ParseExecutorIDFromPodNameutility and unit tests for parsing trailing executor IDs from pod names. - Reworked executor state tracking to enforce a cap via
enforceExecutorStateCap(evict terminated first, then drop newest live if needed). - Added controller-level tests covering churn, high executor IDs, mixed terminal/live maps, and no-cap behavior.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 14 comments.
| File | Description |
|---|---|
| pkg/util/sparkpod.go | Adds trailing-digit executor ID parsing helper used for capped eviction ordering. |
| pkg/util/sparkpod_test.go | Adds table-driven tests for the new parsing helper. |
| internal/controller/sparkapplication/controller.go | Removes “skip by ID” logic and adds a dedicated cap-enforcement step with eviction strategy. |
| internal/controller/sparkapplication/controller_test.go | Adds multiple scenarios validating capped eviction behavior and churn handling. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
da23ab0 to
e32df9d
Compare
…-based skip The id-based skip in updateExecutorState dropped any executor whose ID exceeded MaxTrackedExecutorPerApp and never pruned the state map. On long-running drivers this made executors past the cap invisible and let stale terminated entries crowd out the cap budget, so on executor churn Status.ExecutorState could report zero running executors despite live pods. Replace it with a size-bounded policy enforced at the end of updateExecutorState: evict terminated/UNKNOWN entries oldest-ID-first, and only when the cap is fully occupied by live entries drop the newest-ID-first (logging a warning). Status.ExecutorState semantics shift from cumulative to at-most-cap instantaneous. Add util.ParseExecutorIDFromPodName to recover executor IDs from pod names for terminated entries whose pods are already gone. Signed-off-by: shashankchaudhary <shashankch292@gmail.com>
e32df9d to
921a758
Compare
Purpose of this PR
Fixes a regression introduced in #2181 where executors with IDs above the
MaxTrackedExecutorPerAppcap were silently dropped, and the state map was never pruned — causingStatus.ExecutorStateto report zero running executors on long-running drivers with executor churn.Proposed changes:
updateExecutorStatethat dropped any executor whose numeric ID exceededMaxTrackedExecutorPerAppenforceExecutorStateCap: runs after the missing-pod pass; evicts terminated/UNKNOWN entries oldest-ID-first, and only drops live entries newest-ID-first (with a warning log) when the cap is fully occupied by live executorsutil.ParseExecutorIDFromPodNameto recover executor IDs from pod names for terminated entries whose pods are already goneChange Category
Rationale
PR #2181 introduced the cap by skipping any executor with
ID > MaxTrackedExecutorPerApp. This had two failure modes on long-running drivers:Status.ExecutorState, so the operator's running-count was permanently wrong.On applications with high executor churn (pods deleted, replacements spawn with higher IDs), the net effect was
Status.ExecutorStateshowing zero running executors despite live pods.The fix enforces the cap as a size bound at write time rather than a filter on IDs.
Status.ExecutorStatesemantics shift from cumulative (every ID ever seen, up to cap) to instantaneous (at mostcapentries at any time, preferring live over terminated). No CRD or schema changes;MaxTrackedExecutorPerAppdefault (1000) is unchanged.Checklist
Status.ExecutorStatesemantics covered in Rationale above.)Additional Notes
New test coverage (
internal/controller/sparkapplication/controller_test.go):New unit test (
pkg/util/sparkpod_test.go): table-drivenParseExecutorIDFromPodNamecovering valid names, malformed names, and missing numeric suffix.go test ./pkg/util/... ./internal/controller/sparkapplication/...passes.golangci-lintandgofmtclean.