volcano.sh/volcano@v1.9.0/pkg/scheduler/plugins/priority/priority.go (about) 1 /* 2 Copyright 2018 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package priority 18 19 import ( 20 "k8s.io/klog/v2" 21 22 "volcano.sh/volcano/pkg/scheduler/api" 23 "volcano.sh/volcano/pkg/scheduler/framework" 24 "volcano.sh/volcano/pkg/scheduler/plugins/util" 25 ) 26 27 // PluginName indicates name of volcano scheduler plugin. 28 const PluginName = "priority" 29 30 type priorityPlugin struct { 31 // Arguments given for the plugin 32 pluginArguments framework.Arguments 33 } 34 35 // New return priority plugin 36 func New(arguments framework.Arguments) framework.Plugin { 37 return &priorityPlugin{pluginArguments: arguments} 38 } 39 40 func (pp *priorityPlugin) Name() string { 41 return PluginName 42 } 43 44 func (pp *priorityPlugin) OnSessionOpen(ssn *framework.Session) { 45 taskOrderFn := func(l interface{}, r interface{}) int { 46 lv := l.(*api.TaskInfo) 47 rv := r.(*api.TaskInfo) 48 49 klog.V(4).Infof("Priority TaskOrder: <%v/%v> priority is %v, <%v/%v> priority is %v", 50 lv.Namespace, lv.Name, lv.Priority, rv.Namespace, rv.Name, rv.Priority) 51 52 if lv.Priority == rv.Priority { 53 return 0 54 } 55 56 if lv.Priority > rv.Priority { 57 return -1 58 } 59 60 return 1 61 } 62 63 // Add Task Order function 64 ssn.AddTaskOrderFn(pp.Name(), taskOrderFn) 65 66 jobOrderFn := func(l, r interface{}) int { 67 lv := l.(*api.JobInfo) 68 rv := r.(*api.JobInfo) 69 70 klog.V(4).Infof("Priority JobOrderFn: <%v/%v> priority: %d, <%v/%v> priority: %d", 71 lv.Namespace, lv.Name, lv.Priority, rv.Namespace, rv.Name, rv.Priority) 72 73 if lv.Priority > rv.Priority { 74 return -1 75 } 76 77 if lv.Priority < rv.Priority { 78 return 1 79 } 80 81 return 0 82 } 83 84 ssn.AddJobOrderFn(pp.Name(), jobOrderFn) 85 86 preemptableFn := func(preemptor *api.TaskInfo, preemptees []*api.TaskInfo) ([]*api.TaskInfo, int) { 87 preemptorJob := ssn.Jobs[preemptor.Job] 88 89 var victims []*api.TaskInfo 90 for _, preemptee := range preemptees { 91 preempteeJob := ssn.Jobs[preemptee.Job] 92 if preempteeJob.UID != preemptorJob.UID { 93 if preempteeJob.Priority >= preemptorJob.Priority { // Preemption between Jobs within Queue 94 klog.V(4).Infof("Can not preempt task <%v/%v>"+ 95 "because preemptee job has greater or equal job priority (%d) than preemptor (%d)", 96 preemptee.Namespace, preemptee.Name, preempteeJob.Priority, preemptorJob.Priority) 97 } else { 98 victims = append(victims, preemptee) 99 } 100 } else { // same job's different tasks should compare task's priority 101 if preemptee.Priority >= preemptor.Priority { 102 klog.V(4).Infof("Can not preempt task <%v/%v>"+ 103 "because preemptee task has greater or equal task priority (%d) than preemptor (%d)", 104 preemptee.Namespace, preemptee.Name, preemptee.Priority, preemptor.Priority) 105 } else { 106 victims = append(victims, preemptee) 107 } 108 } 109 } 110 111 klog.V(4).Infof("Victims from Priority plugins are %+v", victims) 112 return victims, util.Permit 113 } 114 ssn.AddPreemptableFn(pp.Name(), preemptableFn) 115 116 jobStarvingFn := func(obj interface{}) bool { 117 ji := obj.(*api.JobInfo) 118 return ji.ReadyTaskNum()+ji.WaitingTaskNum() < int32(len(ji.Tasks)) 119 } 120 ssn.AddJobStarvingFns(pp.Name(), jobStarvingFn) 121 } 122 123 func (pp *priorityPlugin) OnSessionClose(ssn *framework.Session) {}