Skip to content

Commit

Permalink
Fix quota check when a resource has no associated quota (#162)
Browse files Browse the repository at this point in the history
  • Loading branch information
tardieu authored May 3, 2024
1 parent f70abca commit a94c12b
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 9 deletions.
2 changes: 1 addition & 1 deletion internal/controller/dispatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ func (r *Dispatcher) getUnadmittedPodsWeights(ctx context.Context) (map[string]*
for _, pod := range pods.Items {
createdPodsWeightsPair.Add(NewWeightsPairForPod(&pod))
}
weightsPair.Sub(createdPodsWeightsPair)
weightsPair.QuotaSub(createdPodsWeightsPair)
}
nonNegativeWeightsPair := NewWeightsPair(Weights{}, Weights{})
nonNegativeWeightsPair.Max(weightsPair)
Expand Down
8 changes: 5 additions & 3 deletions internal/controller/quota_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package controller

import (
"fmt"
"strings"

mcadv1beta1 "github.com/project-codeflare/mcad/api/v1beta1"
Expand Down Expand Up @@ -82,12 +83,13 @@ func (tracker *QuotaTracker) Satisfies(appWrapperAskWeights *WeightsPair, resour
}
// check if both appwrapper requests and limits fit available resource quota
quotaWeights := quotaState.quota.Clone()
quotaWeights.Sub(quotaState.used)
quotaWeights.Sub(quotaState.allocated)
quotaWeights.QuotaSub(quotaState.used)
quotaWeights.QuotaSub(quotaState.allocated)
var unAdmittedWeights *WeightsPair
if unAdmittedWeights, exists = tracker.unAdmittedWeightsMap[namespace]; exists {
quotaWeights.Sub(unAdmittedWeights)
quotaWeights.QuotaSub(unAdmittedWeights)
}
fmt.Println(quotaWeights)
quotaFits, insufficientResources := appWrapperAskWeights.Fits(quotaWeights)

// mcadLog.Info("QuotaTracker.Satisfies():", "namespace", namespace,
Expand Down
42 changes: 37 additions & 5 deletions internal/controller/weights.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,16 @@ func (w Weights) Sub(r Weights) {
}
}

// Subtract use from quota
func (w Weights) QuotaSub(r Weights) {
for k, v := range r {
if w[k] == nil {
continue // ignore undefined quota
}
w[k].Sub(w[k], v)
}
}

// Add coefficient * weights to receiver
func (w Weights) AddProd(coefficient int32, r Weights) {
for k, v := range r {
Expand Down Expand Up @@ -123,6 +133,28 @@ func (w Weights) Fits(r Weights) (bool, []v1.ResourceName) {
}
}

// Compare receiver to argument
// True if receiver is less than or equal to argument in every dimension where argument is defined
func (w Weights) QuotaFits(r Weights) (bool, []v1.ResourceName) {
insufficient := []v1.ResourceName{}
zero := &inf.Dec{} // shared zero, never mutated
for k, v := range w { // range over receiver not argument
// ignore 0 requests or no quota
if v.Cmp(zero) <= 0 || r[k] == nil {
continue
}
// v > 0 so r[k] must be no less than v
if v.Cmp(r[k]) == 1 {
insufficient = append(insufficient, k)
}
}
if len(insufficient) == 0 {
return true, nil
} else {
return false, insufficient
}
}

// Converts Weights to a ResourceList
func (w Weights) AsResources() v1.ResourceList {
resources := v1.ResourceList{}
Expand Down Expand Up @@ -161,9 +193,9 @@ func (w *WeightsPair) Add(r *WeightsPair) {
}

// Subtract pair of weights from receiver
func (w *WeightsPair) Sub(r *WeightsPair) {
w.requests.Sub(r.requests)
w.limits.Sub(r.limits)
func (w *WeightsPair) QuotaSub(r *WeightsPair) {
w.requests.QuotaSub(r.requests)
w.limits.QuotaSub(r.limits)
}

// Max of two pairs of weights
Expand All @@ -184,8 +216,8 @@ func (w *WeightsPair) Clone() *WeightsPair {
// If False, return list of insufficient resource names
func (w *WeightsPair) Fits(r *WeightsPair) (bool, []v1.ResourceName) {
insufficient := []v1.ResourceName{}
requestsFits, requestsInsufficient := w.requests.Fits(r.requests)
limitsFits, limitsInsufficient := w.limits.Fits(r.limits)
requestsFits, requestsInsufficient := w.requests.QuotaFits(r.requests)
limitsFits, limitsInsufficient := w.limits.QuotaFits(r.limits)
if requestsFits && limitsFits {
return true, insufficient
}
Expand Down

0 comments on commit a94c12b

Please sign in to comment.