Skip to content

Commit

Permalink
scheduler: delete quota inplace
Browse files Browse the repository at this point in the history
Signed-off-by: chuanyun.lcy <[email protected]>
  • Loading branch information
chuanyun.lcy committed Jan 6, 2025
1 parent b3ea5b6 commit 9a2d785
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 6 deletions.
44 changes: 38 additions & 6 deletions pkg/scheduler/plugins/elasticquota/core/group_quota_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -388,12 +388,7 @@ func (gqm *GroupQuotaManager) UpdateQuota(quota *v1alpha1.ElasticQuota, isDelete

quotaName := quota.Name
if isDelete {
// TODO: inplace delete
_, exist := gqm.quotaInfoMap[quotaName]
if !exist {
return fmt.Errorf("get quota info failed, quotaName:%v", quotaName)
}
delete(gqm.quotaInfoMap, quotaName)
return gqm.deleteQuotaNoLock(quota)
} else {
newQuotaInfo := NewQuotaInfoFromQuota(quota)
// update the local quotaInfo's crd
Expand Down Expand Up @@ -1109,3 +1104,40 @@ func shouldBeIgnored(pod *v1.Pod) bool {
return time.Now().After(pod.DeletionTimestamp.Time.Add(time.Duration(*pod.DeletionGracePeriodSeconds) * time.Second))
}
}

func (gqm *GroupQuotaManager) deleteQuotaNoLock(quota *v1alpha1.ElasticQuota) error {
quotaInfo, exist := gqm.quotaInfoMap[quota.Name]
if !exist {
return fmt.Errorf("get quota info failed, quotaName:%v", quota.Name)
}
delete(gqm.quotaInfoMap, quota.Name)

quotaInfo.lock.Lock()
defer quotaInfo.lock.Unlock()
if runtimeQuotaCalculator, exist := gqm.runtimeQuotaCalculatorMap[quotaInfo.ParentName]; exist {
runtimeQuotaCalculator.deleteOneGroup(quotaInfo)
}
delete(gqm.runtimeQuotaCalculatorMap, quota.Name)

// remove scale min.
gqm.scaleMinQuotaManager.remove(quotaInfo.ParentName, quotaInfo.Name)

// remove topo node.
delete(gqm.quotaTopoNodeMap, quota.Name)

// update request
deltaReq := quotav1.Subtract(v1.ResourceList{}, quotaInfo.CalculateInfo.Request)
deltaNonPreemptibleRequest := quotav1.Subtract(v1.ResourceList{}, quotaInfo.CalculateInfo.NonPreemptibleRequest)
if !quotav1.IsZero(deltaReq) || !quotav1.IsZero(deltaNonPreemptibleRequest) {
gqm.updateGroupDeltaRequestNoLock(quotaInfo.ParentName, deltaReq, deltaNonPreemptibleRequest, -1)
}

// update used
deltaUsed := quotav1.Subtract(v1.ResourceList{}, quotaInfo.CalculateInfo.Used)
deltaNonPreemptibleUsed := quotav1.Subtract(v1.ResourceList{}, quotaInfo.CalculateInfo.NonPreemptibleUsed)
if !quotav1.IsZero(deltaUsed) || !quotav1.IsZero(deltaNonPreemptibleUsed) {
gqm.updateGroupDeltaUsedNoLock(quotaInfo.ParentName, deltaUsed, deltaNonPreemptibleUsed, -1)
}

return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ func (qt *quotaTree) updateGuaranteed(groupName string, guarantee int64) {
}
}

func (qt *quotaTree) erase(groupName string) {
if _, exist := qt.quotaNodes[groupName]; exist {
delete(qt.quotaNodes, groupName)
}
}

func (qt *quotaTree) find(groupName string) (bool, *quotaNode) {
if nodeValue, exist := qt.quotaNodes[groupName]; exist {
return exist, nodeValue
Expand Down Expand Up @@ -516,3 +522,22 @@ func createQuantity(value int64, resName v1.ResourceName) resource.Quantity {
}
return q
}

func (qtw *RuntimeQuotaCalculator) deleteOneGroup(quotaInfo *QuotaInfo) {
qtw.lock.Lock()
defer qtw.lock.Unlock()

for resKey := range qtw.resourceKeys {
if exist, _ := qtw.quotaTree[resKey].find(quotaInfo.Name); exist {
qtw.quotaTree[resKey].erase(quotaInfo.Name)
}
}
delete(qtw.groupReqLimit, quotaInfo.Name)
delete(qtw.groupGuaranteed, quotaInfo.Name)

qtw.globalRuntimeVersion++

if klog.V(5).Enabled() {
qtw.logQuotaInfoNoLock("deleteOneGroup finish", quotaInfo)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,30 @@ func (s *ScaleMinQuotaManager) update(parQuotaName, subQuotaName string, subMinQ
s.quotaEnableMinQuotaScaleMap[subQuotaName] = enableScaleMinQuota
}

func (s *ScaleMinQuotaManager) remove(parQuotaName, subQuotaName string) {
s.lock.Lock()
defer s.lock.Unlock()

if !s.quotaEnableMinQuotaScaleMap[subQuotaName] {
if _, ok := s.disableScaleSubsSumMinQuotaMap[parQuotaName]; ok {
s.disableScaleSubsSumMinQuotaMap[parQuotaName] = quotav1.SubtractWithNonNegativeResult(s.disableScaleSubsSumMinQuotaMap[parQuotaName],
s.originalMinQuotaMap[subQuotaName])
}
} else {
if _, ok := s.enableScaleSubsSumMinQuotaMap[parQuotaName]; ok {
s.enableScaleSubsSumMinQuotaMap[parQuotaName] = quotav1.SubtractWithNonNegativeResult(s.enableScaleSubsSumMinQuotaMap[parQuotaName],
s.originalMinQuotaMap[subQuotaName])
}
}

delete(s.originalMinQuotaMap, subQuotaName)
delete(s.quotaEnableMinQuotaScaleMap, subQuotaName)

if klog.V(5).Enabled() {
klog.Infof("ScaleMinQuotaManager remove, parQuota: %v, subQuota: %v ", parQuotaName, subQuotaName)
}
}

func (s *ScaleMinQuotaManager) getScaledMinQuota(newTotalRes v1.ResourceList, parQuotaName, subQuotaName string) (bool, v1.ResourceList) {
s.lock.Lock()
defer s.lock.Unlock()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,74 @@ func TestScaleMinQuotaWhenOverRootResInfo_Update(t *testing.T) {
}
}
}

func TestScaleMinQuotaWhenOverRootResInfo_Remove(t *testing.T) {
info := NewScaleMinQuotaManager()
if len(info.enableScaleSubsSumMinQuotaMap) != 0 ||
len(info.disableScaleSubsSumMinQuotaMap) != 0 || len(info.originalMinQuotaMap) != 0 || len(info.quotaEnableMinQuotaScaleMap) != 0 {
t.Errorf("error")
}
{
parQuotaName := "100"
subQuotaName := "1"
subMinQuota := createResourceList(50, 50)
enableScaleMinQuota := false
info.update(parQuotaName, subQuotaName, subMinQuota, enableScaleMinQuota)

if len(info.enableScaleSubsSumMinQuotaMap) != 1 ||
len(info.disableScaleSubsSumMinQuotaMap) != 1 || len(info.originalMinQuotaMap) != 1 || len(info.quotaEnableMinQuotaScaleMap) != 1 {
t.Errorf("error")
}
if !quotav1.Equals(info.enableScaleSubsSumMinQuotaMap["100"], v1.ResourceList{}) ||
!quotav1.Equals(info.disableScaleSubsSumMinQuotaMap["100"], createResourceList(50, 50)) ||
!quotav1.Equals(info.originalMinQuotaMap["1"], createResourceList(50, 50)) || info.quotaEnableMinQuotaScaleMap["1"] != false {
t.Error("error")
}
}
{
parQuotaName := "100"
subQuotaName := "2"
subMinQuota := createResourceList(60, 60)
enableScaleMinQuota := true
info.update(parQuotaName, subQuotaName, subMinQuota, enableScaleMinQuota)

if len(info.enableScaleSubsSumMinQuotaMap) != 1 ||
len(info.disableScaleSubsSumMinQuotaMap) != 1 || len(info.originalMinQuotaMap) != 2 || len(info.quotaEnableMinQuotaScaleMap) != 2 {
t.Errorf("error")
}

if !quotav1.Equals(info.enableScaleSubsSumMinQuotaMap["100"], createResourceList(60, 60)) ||
!quotav1.Equals(info.disableScaleSubsSumMinQuotaMap["100"], createResourceList(50, 50)) ||
!quotav1.Equals(info.originalMinQuotaMap["1"], createResourceList(50, 50)) || info.quotaEnableMinQuotaScaleMap["1"] != false ||
!quotav1.Equals(info.originalMinQuotaMap["2"], createResourceList(60, 60)) || info.quotaEnableMinQuotaScaleMap["2"] != true {
t.Error("error")
}
}
{
info.remove("100", "1")

if len(info.enableScaleSubsSumMinQuotaMap) != 1 ||
len(info.disableScaleSubsSumMinQuotaMap) != 1 || len(info.originalMinQuotaMap) != 1 || len(info.quotaEnableMinQuotaScaleMap) != 1 {
t.Errorf("error")
}

if !quotav1.Equals(info.enableScaleSubsSumMinQuotaMap["100"], createResourceList(60, 60)) ||
!quotav1.Equals(info.disableScaleSubsSumMinQuotaMap["100"], createResourceList(0, 0)) ||
!quotav1.Equals(info.originalMinQuotaMap["2"], createResourceList(60, 60)) || info.quotaEnableMinQuotaScaleMap["2"] != true {
t.Error("error")
}
}
{
info.remove("100", "2")

if len(info.enableScaleSubsSumMinQuotaMap) != 1 ||
len(info.disableScaleSubsSumMinQuotaMap) != 1 || len(info.originalMinQuotaMap) != 0 || len(info.quotaEnableMinQuotaScaleMap) != 0 {
t.Errorf("error")
}

if !quotav1.Equals(info.enableScaleSubsSumMinQuotaMap["100"], createResourceList(0, 0)) ||
!quotav1.Equals(info.disableScaleSubsSumMinQuotaMap["100"], createResourceList(0, 0)) {
t.Error("error")
}
}
}

0 comments on commit 9a2d785

Please sign in to comment.