Skip to content

Commit 26c0127

Browse files
kannon92claude
andcommitted
Graduate PrioritySortingWithinCohort feature gate to GA
Set PrioritySortingWithinCohort to GA with LockToDefault: true at version 0.17. Remove all conditional code paths guarded by the feature gate since priority sorting within cohorts is now always enabled. Remove associated disabled-feature test cases and update documentation to no longer reference the ability to disable the feature. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent bdabad9 commit 26c0127

File tree

10 files changed

+24
-179
lines changed

10 files changed

+24
-179
lines changed

pkg/features/kube_features.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ var defaultVersionedFeatureGates = map[featuregate.Feature]featuregate.Versioned
269269
},
270270
PrioritySortingWithinCohort: {
271271
{Version: version.MustParse("0.6"), Default: true, PreRelease: featuregate.Beta},
272+
{Version: version.MustParse("0.17"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 0.19
272273
},
273274
MultiKueue: {
274275
{Version: version.MustParse("0.6"), Default: false, PreRelease: featuregate.Alpha},

pkg/scheduler/fair_sharing_iterator.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import (
2525

2626
kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
2727
schdcache "sigs.k8s.io/kueue/pkg/cache/scheduler"
28-
"sigs.k8s.io/kueue/pkg/features"
2928
"sigs.k8s.io/kueue/pkg/util/priority"
3029
"sigs.k8s.io/kueue/pkg/workload"
3130
)
@@ -173,12 +172,10 @@ func (e *entryComparer) less(a, b *entry, parentCohort kueue.CohortReference) bo
173172
}
174173

175174
// 2: Priority
176-
if features.Enabled(features.PrioritySortingWithinCohort) {
177-
p1 := priority.Priority(a.Obj)
178-
p2 := priority.Priority(b.Obj)
179-
if p1 != p2 {
180-
return p1 > p2
181-
}
175+
p1 := priority.Priority(a.Obj)
176+
p2 := priority.Priority(b.Obj)
177+
if p1 != p2 {
178+
return p1 > p2
182179
}
183180

184181
// 3: FIFO

pkg/scheduler/scheduler.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -737,13 +737,11 @@ func (e entryOrdering) Less(i, j int) bool {
737737
return aBorrows < bBorrows
738738
}
739739

740-
// 2. Higher priority first if not disabled.
741-
if features.Enabled(features.PrioritySortingWithinCohort) {
742-
p1 := priority.Priority(a.Obj)
743-
p2 := priority.Priority(b.Obj)
744-
if p1 != p2 {
745-
return p1 > p2
746-
}
740+
// 2. Higher priority first.
741+
p1 := priority.Priority(a.Obj)
742+
p2 := priority.Priority(b.Obj)
743+
if p1 != p2 {
744+
return p1 > p2
747745
}
748746

749747
// 3. FIFO.

pkg/scheduler/scheduler_test.go

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7826,54 +7826,24 @@ func TestEntryOrdering(t *testing.T) {
78267826
for _, tc := range []struct {
78277827
name string
78287828
input []entry
7829-
prioritySorting bool
78307829
workloadOrdering workload.Ordering
78317830
wantOrder []string
78327831
}{
78337832
{
7834-
name: "Priority sorting is enabled (default) using pods-ready Eviction timestamp (default)",
7833+
name: "Priority sorting using pods-ready Eviction timestamp (default)",
78357834
input: input,
7836-
prioritySorting: true,
78377835
workloadOrdering: workload.Ordering{PodsReadyRequeuingTimestamp: config.EvictionTimestamp},
78387836
wantOrder: []string{"new_high_pri", "old", "recently_evicted", "new", "high_pri_borrowing", "old_borrowing", "evicted_borrowing", "new_borrowing", "high_pri_borrowing_more"},
78397837
},
78407838
{
7841-
name: "Priority sorting is enabled (default) using pods-ready Creation timestamp",
7839+
name: "Priority sorting using pods-ready Creation timestamp",
78427840
input: input,
7843-
prioritySorting: true,
78447841
workloadOrdering: workload.Ordering{PodsReadyRequeuingTimestamp: config.CreationTimestamp},
78457842
wantOrder: []string{"new_high_pri", "recently_evicted", "old", "new", "high_pri_borrowing", "old_borrowing", "evicted_borrowing", "new_borrowing", "high_pri_borrowing_more"},
78467843
},
78477844
{
7848-
name: "Priority sorting is disabled using pods-ready Eviction timestamp",
7849-
input: input,
7850-
prioritySorting: false,
7851-
workloadOrdering: workload.Ordering{PodsReadyRequeuingTimestamp: config.EvictionTimestamp},
7852-
wantOrder: []string{"old", "recently_evicted", "new", "new_high_pri", "old_borrowing", "evicted_borrowing", "high_pri_borrowing", "new_borrowing", "high_pri_borrowing_more"},
7853-
},
7854-
{
7855-
name: "Priority sorting is disabled using pods-ready Creation timestamp",
7856-
input: input,
7857-
prioritySorting: false,
7858-
workloadOrdering: workload.Ordering{PodsReadyRequeuingTimestamp: config.CreationTimestamp},
7859-
wantOrder: []string{"recently_evicted", "old", "new", "new_high_pri", "old_borrowing", "evicted_borrowing", "high_pri_borrowing", "new_borrowing", "high_pri_borrowing_more"},
7860-
},
7861-
{
7862-
name: "Some workloads are preempted; Priority sorting is disabled",
7863-
input: inputForOrderingPreemptedWorkloads,
7864-
prioritySorting: false,
7865-
wantOrder: []string{
7866-
"old-mid-recently-preempted-in-queue",
7867-
"old-mid-not-preempted-yet",
7868-
"old-mid-recently-reclaimed-while-borrowing",
7869-
"preemptor",
7870-
"old-mid-more-recently-reclaimed-while-borrowing",
7871-
},
7872-
},
7873-
{
7874-
name: "Some workloads are preempted; Priority sorting is enabled",
7875-
input: inputForOrderingPreemptedWorkloads,
7876-
prioritySorting: true,
7845+
name: "Some workloads are preempted",
7846+
input: inputForOrderingPreemptedWorkloads,
78777847
wantOrder: []string{
78787848
"preemptor",
78797849
"old-mid-recently-preempted-in-queue",
@@ -7884,7 +7854,6 @@ func TestEntryOrdering(t *testing.T) {
78847854
},
78857855
} {
78867856
t.Run(tc.name, func(t *testing.T) {
7887-
features.SetFeatureGateDuringTest(t, features.PrioritySortingWithinCohort, tc.prioritySorting)
78887857
ctx, _ := utiltesting.ContextWithLog(t)
78897858
iter := makeIterator(ctx, tc.input, tc.workloadOrdering, false)
78907859
order := make([]string, len(tc.input))

pkg/workload/workload.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,15 +1116,6 @@ func (o Ordering) GetQueueOrderTimestamp(w *kueue.Workload) *metav1.Time {
11161116
if evictedCond, evictedByCheck := IsEvictedByAdmissionCheck(w); evictedByCheck {
11171117
return &evictedCond.LastTransitionTime
11181118
}
1119-
if !features.Enabled(features.PrioritySortingWithinCohort) {
1120-
if preemptedCond := apimeta.FindStatusCondition(w.Status.Conditions, kueue.WorkloadPreempted); preemptedCond != nil &&
1121-
preemptedCond.Status == metav1.ConditionTrue &&
1122-
preemptedCond.Reason == kueue.InCohortReclaimWhileBorrowingReason {
1123-
// We add an epsilon to make sure the timestamp of the preempted
1124-
// workload is strictly greater that the preemptor's
1125-
return &metav1.Time{Time: preemptedCond.LastTransitionTime.Add(time.Millisecond)}
1126-
}
1127-
}
11281119
return &w.CreationTimestamp
11291120
}
11301121

site/content/en/docs/concepts/cluster_queue.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,7 @@ semantics:
240240

241241
{{% alert title="Note" color="primary" %}}
242242
Within a Cohort, Kueue prioritizes scheduling workloads that will fit under `nominalQuota`.
243-
By default, if multiple workloads require `borrowing`, Kueue will try to schedule workloads with higher [priority](/docs/concepts/workload#priority) first.
244-
If the feature gate `PrioritySortingWithinCohort=false` is set, Kueue will try to schedule workloads with the earliest `.metadata.creationTimestamp`.
243+
If multiple workloads require `borrowing`, Kueue will try to schedule workloads with higher [priority](/docs/concepts/workload#priority) first.
245244
{{% /alert %}}
246245

247246
You can influence some semantics of flavor selection and borrowing

site/content/zh-CN/docs/concepts/cluster_queue.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,9 +219,8 @@ ClusterQueue 借用配额。
219219

220220
{{% alert title="注意" color="primary" %}}
221221
在 cohort 中,Kueue 优先安排将适合 under `nominalQuota` 的工作负载。
222-
默认情况下,如果多个工作负载需要 `borrowing`,Kueue 将尝试安排优先级更高的工作负载
222+
如果多个工作负载需要 `borrowing`,Kueue 将尝试安排优先级更高的工作负载
223223
[priority](/docs/concepts/workload#priority) 首先。
224-
如果 feature gate `PrioritySortingWithinCohort=false` 设置,Kueue 将尝试安排最早的 `.metadata.creationTimestamp` 的工作负载。
225224
{{% /alert %}}
226225

227226
你可以设置一个 [`flavorFungibility`](/docs/concepts/cluster_queue#flavorfungibility) 来影响一些规格选择和借用的语义。

site/data/featuregates/versioned_feature_list.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@
161161
lockToDefault: false
162162
preRelease: Beta
163163
version: "0.6"
164+
- default: true
165+
lockToDefault: true
166+
preRelease: GA
167+
version: "0.17"
164168
- name: PropagateBatchJobLabelsToWorkload
165169
versionedSpecs:
166170
- default: true

test/compatibility_lifecycle/reference/versioned_feature_list.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@
161161
lockToDefault: false
162162
preRelease: Beta
163163
version: "0.6"
164+
- default: true
165+
lockToDefault: true
166+
preRelease: GA
167+
version: "0.17"
164168
- name: PropagateBatchJobLabelsToWorkload
165169
versionedSpecs:
166170
- default: true

test/integration/singlecluster/scheduler/preemption_test.go

Lines changed: 0 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -857,123 +857,6 @@ var _ = ginkgo.Describe("Preemption", func() {
857857
})
858858
})
859859

860-
ginkgo.Context("When borrowWithinCohort is used and PrioritySortingWithinCohort disabled", func() {
861-
var (
862-
aCQ, bCQ, cCQ *kueue.ClusterQueue
863-
aLQ, bLQ *kueue.LocalQueue
864-
defaultFlavor *kueue.ResourceFlavor
865-
)
866-
867-
ginkgo.BeforeEach(func() {
868-
features.SetFeatureGateDuringTest(ginkgo.GinkgoTB(), features.PrioritySortingWithinCohort, false)
869-
defaultFlavor = utiltestingapi.MakeResourceFlavor("default").Obj()
870-
util.MustCreate(ctx, k8sClient, defaultFlavor)
871-
872-
aCQ = utiltestingapi.MakeClusterQueue("a-cq").
873-
Cohort("all").
874-
ResourceGroup(
875-
*utiltestingapi.MakeFlavorQuotas("default").Resource(corev1.ResourceCPU, "0", "10").Obj(),
876-
).
877-
FlavorFungibility(kueue.FlavorFungibility{
878-
WhenCanBorrow: kueue.MayStopSearch,
879-
WhenCanPreempt: kueue.MayStopSearch,
880-
}).
881-
Preemption(kueue.ClusterQueuePreemption{
882-
ReclaimWithinCohort: kueue.PreemptionPolicyAny,
883-
WithinClusterQueue: kueue.PreemptionPolicyLowerPriority,
884-
}).
885-
Obj()
886-
util.MustCreate(ctx, k8sClient, aCQ)
887-
aLQ = utiltestingapi.MakeLocalQueue("a-lq", ns.Name).ClusterQueue(aCQ.Name).Obj()
888-
util.MustCreate(ctx, k8sClient, aLQ)
889-
890-
bCQ = utiltestingapi.MakeClusterQueue("b-cq").
891-
Cohort("all").
892-
ResourceGroup(
893-
*utiltestingapi.MakeFlavorQuotas("default").Resource(corev1.ResourceCPU, "5", "5").Obj(),
894-
).
895-
FlavorFungibility(kueue.FlavorFungibility{
896-
WhenCanBorrow: kueue.MayStopSearch,
897-
WhenCanPreempt: kueue.MayStopSearch,
898-
}).
899-
Preemption(kueue.ClusterQueuePreemption{
900-
ReclaimWithinCohort: kueue.PreemptionPolicyAny,
901-
WithinClusterQueue: kueue.PreemptionPolicyLowerPriority,
902-
BorrowWithinCohort: &kueue.BorrowWithinCohort{
903-
Policy: kueue.BorrowWithinCohortPolicyLowerPriority,
904-
MaxPriorityThreshold: ptr.To(veryHighPriority),
905-
},
906-
}).
907-
Obj()
908-
util.MustCreate(ctx, k8sClient, bCQ)
909-
bLQ = utiltestingapi.MakeLocalQueue("b-lq", ns.Name).ClusterQueue(bCQ.Name).Obj()
910-
util.MustCreate(ctx, k8sClient, bLQ)
911-
912-
cCQ = utiltestingapi.MakeClusterQueue("c-cq").
913-
Cohort("all").
914-
ResourceGroup(
915-
*utiltestingapi.MakeFlavorQuotas("default").Resource(corev1.ResourceCPU, "5").Obj(),
916-
).
917-
FlavorFungibility(kueue.FlavorFungibility{
918-
WhenCanBorrow: kueue.MayStopSearch,
919-
WhenCanPreempt: kueue.MayStopSearch,
920-
}).
921-
Preemption(kueue.ClusterQueuePreemption{
922-
ReclaimWithinCohort: kueue.PreemptionPolicyAny,
923-
WithinClusterQueue: kueue.PreemptionPolicyLowerPriority,
924-
}).
925-
Obj()
926-
util.MustCreate(ctx, k8sClient, cCQ)
927-
})
928-
929-
ginkgo.AfterEach(func() {
930-
gomega.Expect(util.DeleteWorkloadsInNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
931-
util.ExpectObjectToBeDeleted(ctx, k8sClient, aCQ, true)
932-
util.ExpectObjectToBeDeleted(ctx, k8sClient, bCQ, true)
933-
util.ExpectObjectToBeDeleted(ctx, k8sClient, cCQ, true)
934-
util.ExpectObjectToBeDeleted(ctx, k8sClient, defaultFlavor, true)
935-
})
936-
937-
ginkgo.It("should allow preempting workloads while borrowing", func() {
938-
var aWl, b1Wl, b2Wl *kueue.Workload
939-
940-
ginkgo.By("Create a mid priority workload in aCQ and await for admission", func() {
941-
aWl = utiltestingapi.MakeWorkload("a-low", ns.Name).
942-
Queue(kueue.LocalQueueName(aLQ.Name)).
943-
Priority(midPriority).
944-
Request(corev1.ResourceCPU, "4").
945-
Obj()
946-
util.MustCreate(ctx, k8sClient, aWl)
947-
util.ExpectWorkloadsToBeAdmitted(ctx, k8sClient, aWl)
948-
})
949-
950-
ginkgo.By("Create a high priority workload b1 in bCQ and await for admission", func() {
951-
b1Wl = utiltestingapi.MakeWorkload("b1-high", ns.Name).
952-
Queue(kueue.LocalQueueName(bLQ.Name)).
953-
Priority(highPriority).
954-
Request(corev1.ResourceCPU, "4").
955-
Obj()
956-
util.MustCreate(ctx, k8sClient, b1Wl)
957-
util.ExpectWorkloadsToBeAdmitted(ctx, k8sClient, b1Wl)
958-
})
959-
960-
ginkgo.By("Create a high priority workload b2 in bCQ", func() {
961-
b2Wl = utiltestingapi.MakeWorkload("b2-high", ns.Name).
962-
Queue(kueue.LocalQueueName(bLQ.Name)).
963-
Priority(highPriority).
964-
Request(corev1.ResourceCPU, "4").
965-
Obj()
966-
util.MustCreate(ctx, k8sClient, b2Wl)
967-
})
968-
969-
ginkgo.By("Await for preemption of the workload in aCQ and admission of b2", func() {
970-
util.FinishEvictionForWorkloads(ctx, k8sClient, aWl)
971-
util.ExpectWorkloadsToBePending(ctx, k8sClient, aWl)
972-
util.ExpectWorkloadsToBeAdmitted(ctx, k8sClient, b2Wl)
973-
})
974-
})
975-
})
976-
977860
ginkgo.Context("In a multi-level cohort", func() {
978861
var rootCohort, guaranteedCohort *kueue.Cohort
979862
var bestEffortCQ, guaranteedCQ *kueue.ClusterQueue

0 commit comments

Comments
 (0)