You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@yunikorn.apache.org by ma...@apache.org on 2026/08/13 12:14:28 UTC

(yunikorn-core) branch master updated: [YUNIKORN-3331] Run preemption preconditions before instantiating preemptor (#1125)

This is an automated email from the ASF dual-hosted git repository.

manirajv06 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/yunikorn-core.git


The following commit(s) were added to refs/heads/master by this push:
     new ffab9399 [YUNIKORN-3331] Run preemption preconditions before instantiating preemptor (#1125)
ffab9399 is described below

commit ffab9399e0343f287443436406845cf7d8b79b0c
Author: stantheman0128 <st...@gmail.com>
AuthorDate: Thu Aug 13 17:41:58 2026 +0530

    [YUNIKORN-3331] Run preemption preconditions before instantiating preemptor (#1125)
    
    NewPreemptor would be instantiated only if required based on the CheckPreconditions outcome
    
    Closes: #1125
    
    Signed-off-by: mani <ma...@gmail.com>
---
 pkg/scheduler/objects/application.go     |  5 ++---
 pkg/scheduler/objects/preemption.go      | 14 +++++++-------
 pkg/scheduler/objects/preemption_test.go | 27 ++++++++++++++-------------
 3 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/pkg/scheduler/objects/application.go b/pkg/scheduler/objects/application.go
index 2d6ced96..d7d9ab68 100644
--- a/pkg/scheduler/objects/application.go
+++ b/pkg/scheduler/objects/application.go
@@ -1561,10 +1561,8 @@ func (sa *Application) tryPreemption(headRoom *resources.Resource, preemptionDel
 		ask.LogAllocationFailure(common.PreemptionMaxAttemptsExhausted, true)
 		return nil, false
 	}
-	preemptor := NewPreemptor(sa, headRoom, preemptionDelay, ask, iterator, nodesTried)
-
 	// validate prerequisites for preemption of an ask and mark ask for preemption if successful
-	if !preemptor.CheckPreconditions() {
+	if !CheckPreconditions(ask, preemptionDelay) {
 		ask.LogAllocationFailure(common.PreemptionPreconditionsFailed, true)
 		return nil, false
 	}
@@ -1575,6 +1573,7 @@ func (sa *Application) tryPreemption(headRoom *resources.Resource, preemptionDel
 	defer metrics.GetSchedulerMetrics().ObserveTryPreemptionLatency(tryPreemptionStart)
 
 	// attempt preemption
+	preemptor := NewPreemptor(sa, headRoom, preemptionDelay, ask, iterator, nodesTried)
 	return preemptor.TryPreemption()
 }
 
diff --git a/pkg/scheduler/objects/preemption.go b/pkg/scheduler/objects/preemption.go
index 12c0a08b..788bbbdd 100644
--- a/pkg/scheduler/objects/preemption.go
+++ b/pkg/scheduler/objects/preemption.go
@@ -89,36 +89,36 @@ func NewPreemptor(application *Application, headRoom *resources.Resource, preemp
 
 // CheckPreconditions performs simple sanity checks designed to determine if preemption should be attempted
 // for an ask. If checks succeed, updates the ask preemption check time.
-func (p *Preemptor) CheckPreconditions() bool {
+func CheckPreconditions(ask *Allocation, preemptionDelay time.Duration) bool {
 	now := time.Now()
 
 	// skip if ask is not allowed to preempt other tasks
-	if !p.ask.IsAllowPreemptOther() {
+	if !ask.IsAllowPreemptOther() {
 		return false
 	}
 
 	// skip if ask has previously triggered preemption
-	if p.ask.HasTriggeredPreemption() {
+	if ask.HasTriggeredPreemption() {
 		return false
 	}
 
 	// skip if ask requires a specific node (this should be handled by required node preemption algorithm)
-	if p.ask.GetRequiredNode() != "" {
+	if ask.GetRequiredNode() != "" {
 		return false
 	}
 
 	// skip if preemption delay has not yet passed
-	if now.Before(p.ask.GetCreateTime().Add(p.preemptionDelay)) {
+	if now.Before(ask.GetCreateTime().Add(preemptionDelay)) {
 		return false
 	}
 
 	// skip if attempt frequency hasn't been reached again
-	if now.Before(p.ask.GetPreemptCheckTime().Add(preemptAttemptFrequency)) {
+	if now.Before(ask.GetPreemptCheckTime().Add(preemptAttemptFrequency)) {
 		return false
 	}
 
 	// mark this ask as having been checked recently to avoid doing extra work in the next scheduling cycle
-	p.ask.UpdatePreemptCheckTime()
+	ask.UpdatePreemptCheckTime()
 
 	return true
 }
diff --git a/pkg/scheduler/objects/preemption_test.go b/pkg/scheduler/objects/preemption_test.go
index 333f6cd3..addfb387 100644
--- a/pkg/scheduler/objects/preemption_test.go
+++ b/pkg/scheduler/objects/preemption_test.go
@@ -135,43 +135,44 @@ func TestCheckPreconditions(t *testing.T) {
 	ask.createTime = time.Now().Add(-1 * time.Minute)
 	err = app.AddAllocationAsk(ask)
 	assert.NilError(t, err)
-	preemptor := NewPreemptor(app, resources.NewResource(), 30*time.Second, ask, iterator(), false)
+	// the checks run without a preemptor: they only need the ask and the delay
+	preemptionDelay := 30 * time.Second
 
 	// success case
-	assert.Assert(t, preemptor.CheckPreconditions(), "preconditions failed")
+	assert.Assert(t, CheckPreconditions(ask, preemptionDelay), "preconditions failed")
 	ask.preemptCheckTime = time.Now().Add(-1 * time.Minute)
 
 	// verify ask which opted-out of preempting others is disqualified
 	ask.allowPreemptOther = false
-	assert.Assert(t, !preemptor.CheckPreconditions(), "preconditions succeeded when ask doesn't allow preempt other")
+	assert.Assert(t, !CheckPreconditions(ask, preemptionDelay), "preconditions succeeded when ask doesn't allow preempt other")
 	ask.allowPreemptOther = true
-	assert.Assert(t, preemptor.CheckPreconditions(), "preconditions failed")
+	assert.Assert(t, CheckPreconditions(ask, preemptionDelay), "preconditions failed")
 	ask.preemptCheckTime = time.Now().Add(-1 * time.Minute)
 
 	// verify previously triggered preemption disqualifies ask
 	ask.MarkTriggeredPreemption()
-	assert.Assert(t, !preemptor.CheckPreconditions(), "preconditions succeeded when ask has already triggered preemption")
+	assert.Assert(t, !CheckPreconditions(ask, preemptionDelay), "preconditions succeeded when ask has already triggered preemption")
 	ask.preemptionTriggered = false
-	assert.Assert(t, preemptor.CheckPreconditions(), "preconditions failed")
+	assert.Assert(t, CheckPreconditions(ask, preemptionDelay), "preconditions failed")
 	ask.preemptCheckTime = time.Now().Add(-1 * time.Minute)
 
 	// verify that ask requiring a specific node is disqualified
 	ask.SetRequiredNode("node1")
-	assert.Assert(t, !preemptor.CheckPreconditions(), "preconditions succeeded with ask requiring a specific node")
+	assert.Assert(t, !CheckPreconditions(ask, preemptionDelay), "preconditions succeeded with ask requiring a specific node")
 	ask.SetRequiredNode("")
-	assert.Assert(t, preemptor.CheckPreconditions(), "preconditions failed")
+	assert.Assert(t, CheckPreconditions(ask, preemptionDelay), "preconditions failed")
 	ask.preemptCheckTime = time.Now().Add(-1 * time.Minute)
 
 	// verify that recently created ask is disqualified
 	ask.createTime = time.Now()
-	assert.Assert(t, !preemptor.CheckPreconditions(), "preconditions succeeded with newly-created ask")
+	assert.Assert(t, !CheckPreconditions(ask, preemptionDelay), "preconditions succeeded with newly-created ask")
 	ask.createTime = time.Now().Add(-1 * time.Minute)
-	assert.Assert(t, preemptor.CheckPreconditions(), "preconditions failed")
+	assert.Assert(t, CheckPreconditions(ask, preemptionDelay), "preconditions failed")
 	ask.preemptCheckTime = time.Now().Add(-1 * time.Minute)
 
 	// verify that recently checked ask is disqualified
 	ask.preemptCheckTime = time.Now()
-	assert.Assert(t, !preemptor.CheckPreconditions(), "preconditions succeeded with recently tried ask")
+	assert.Assert(t, !CheckPreconditions(ask, preemptionDelay), "preconditions succeeded with recently tried ask")
 	getNode := func(nodeID string) *Node {
 		return node
 	}
@@ -180,8 +181,8 @@ func TestCheckPreconditions(t *testing.T) {
 	assert.Check(t, result == nil, "unexpected result")
 	assertAllocationLog(t, ask, []string{common.PreemptionPreconditionsFailed, common.PreemptionDoesNotHelp})
 	ask.preemptCheckTime = time.Now().Add(-1 * time.Minute)
-	assert.Assert(t, preemptor.CheckPreconditions(), "preconditions failed")
-	assert.Assert(t, !preemptor.CheckPreconditions(), "preconditions succeeded on successive run")
+	assert.Assert(t, CheckPreconditions(ask, preemptionDelay), "preconditions failed")
+	assert.Assert(t, !CheckPreconditions(ask, preemptionDelay), "preconditions succeeded on successive run")
 }
 
 func TestCheckPreemptionQueueGuarantees(t *testing.T) {


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@yunikorn.apache.org
For additional commands, e-mail: issues-help@yunikorn.apache.org