64 lines
2 KiB
Go
64 lines
2 KiB
Go
|
package schedUtils
|
||
|
|
||
|
import (
|
||
|
"bitbucket.org/sunybingcloud/elektron/def"
|
||
|
"bitbucket.org/sunybingcloud/elektron/utilities"
|
||
|
)
|
||
|
|
||
|
// Criteria for resizing the scheduling window.
|
||
|
type SchedulingWindowResizingCriteria string
|
||
|
|
||
|
var SchedWindowResizingCritToStrategy = map[SchedulingWindowResizingCriteria]schedWindowResizingStrategy{
|
||
|
"fillNextOfferCycle": &fillNextOfferCycle{},
|
||
|
}
|
||
|
|
||
|
// Interface for a scheduling window resizing strategy.
|
||
|
type schedWindowResizingStrategy interface {
|
||
|
// Apply the window resizing strategy and return the news scheduling window size.
|
||
|
Apply(func() interface{}) int
|
||
|
}
|
||
|
|
||
|
// Scheduling window resizing strategy that attempts to resize the scheduling window
|
||
|
// to include as many tasks as possible so as to make the most use of the next offer cycle.
|
||
|
type fillNextOfferCycle struct{}
|
||
|
|
||
|
func (s *fillNextOfferCycle) Apply(getArgs func() interface{}) int {
|
||
|
return s.apply(getArgs().([]def.Task))
|
||
|
}
|
||
|
|
||
|
// Loop over the unscheduled tasks, in submission order, and determine the maximum
|
||
|
// number of tasks that can be scheduled in the next offer cycle.
|
||
|
// As the offers get smaller and smaller, this approach might lead to an increase in internal fragmentation.
|
||
|
//
|
||
|
// Note: To be able to make the most use of the next offer cycle, one would need to perform a non-polynomial search
|
||
|
// which is computationally expensive.
|
||
|
func (s *fillNextOfferCycle) apply(taskQueue []def.Task) int {
|
||
|
clusterwideResourceCount := utilities.GetClusterwideResourceAvailability()
|
||
|
newSchedWindow := 0
|
||
|
filledCPU := 0.0
|
||
|
filledRAM := 0.0
|
||
|
|
||
|
// Can we schedule another task.
|
||
|
canSchedule := func(t def.Task) bool {
|
||
|
if ((filledCPU + t.CPU) <= clusterwideResourceCount.UnusedCPU) &&
|
||
|
((filledRAM + t.RAM) <= clusterwideResourceCount.UnusedRAM) {
|
||
|
return true
|
||
|
}
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
for _, task := range taskQueue {
|
||
|
for i := *task.Instances; i > 0; i-- {
|
||
|
if canSchedule(task) {
|
||
|
filledCPU += task.CPU
|
||
|
filledRAM += task.RAM
|
||
|
newSchedWindow++
|
||
|
} else {
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
break
|
||
|
}
|
||
|
return newSchedWindow
|
||
|
}
|