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 <[email protected]>
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 <[email protected]>
---
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: [email protected]
For additional commands, e-mail: [email protected]