2019-10-31 14:32:46 -04:00
// Copyright (C) 2018 spdfg
2018-11-08 20:07:06 -05:00
//
2018-10-06 20:03:14 -07:00
// This file is part of Elektron.
2018-11-08 20:07:06 -05:00
//
2018-10-06 20:03:14 -07:00
// Elektron is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
2018-11-08 20:07:06 -05:00
//
2018-10-06 20:03:14 -07:00
// Elektron is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
2018-11-08 20:07:06 -05:00
//
2018-10-06 20:03:14 -07:00
// You should have received a copy of the GNU General Public License
// along with Elektron. If not, see <http://www.gnu.org/licenses/>.
2018-11-08 20:07:06 -05:00
//
2018-10-06 20:03:14 -07:00
2016-10-13 17:15:09 -04:00
package schedulers
import (
2018-11-08 20:07:06 -05:00
"fmt"
2018-09-30 18:23:38 -07:00
mesos "github.com/mesos/mesos-go/api/v0/mesosproto"
sched "github.com/mesos/mesos-go/api/v0/scheduler"
"github.com/pkg/errors"
2019-10-31 14:32:46 -04:00
"github.com/spdfg/elektron/constants"
"github.com/spdfg/elektron/def"
elekLogDef "github.com/spdfg/elektron/logging/def"
"github.com/spdfg/elektron/utilities"
"github.com/spdfg/elektron/utilities/mesosUtils"
2018-11-08 20:07:06 -05:00
"log"
2016-10-13 17:15:09 -04:00
)
2018-01-30 14:12:37 -05:00
func coLocated ( tasks map [ string ] bool , s BaseScheduler ) {
2016-10-13 17:15:09 -04:00
for task := range tasks {
2018-10-04 13:45:31 -04:00
s . Log ( elekLogDef . GENERAL , task )
2016-10-13 17:15:09 -04:00
}
2018-10-04 13:45:31 -04:00
s . Log ( elekLogDef . GENERAL , "---------------------" )
2016-10-13 17:15:09 -04:00
}
2017-01-28 21:09:43 -05:00
2017-09-28 15:36:47 -04:00
// Get the powerClass of the given hostname.
2017-02-09 18:05:38 -05:00
func hostToPowerClass ( hostName string ) string {
for powerClass , hosts := range constants . PowerClasses {
2017-03-24 16:28:49 -04:00
if _ , ok := hosts [ hostName ] ; ok {
2017-02-09 18:05:38 -05:00
return powerClass
2017-01-28 21:09:43 -05:00
}
}
2017-02-09 18:05:38 -05:00
return ""
2017-01-28 21:09:43 -05:00
}
2017-09-26 13:17:47 -04:00
2018-01-19 21:20:43 +00:00
// scheduler policy options to help initialize schedulers
2018-10-04 19:24:16 -04:00
type SchedulerOptions func ( e ElectronScheduler ) error
2017-09-26 13:17:47 -04:00
2018-10-04 19:24:16 -04:00
func WithSchedPolicy ( schedPolicyName string ) SchedulerOptions {
2018-01-19 21:20:43 +00:00
return func ( s ElectronScheduler ) error {
if schedPolicy , ok := SchedPolicies [ schedPolicyName ] ; ! ok {
return errors . New ( "Incorrect scheduling policy." )
} else {
2018-01-30 14:12:37 -05:00
s . ( * BaseScheduler ) . curSchedPolicy = schedPolicy
2018-01-19 21:20:43 +00:00
return nil
}
}
}
2018-10-04 19:24:16 -04:00
func WithTasks ( ts [ ] def . Task ) SchedulerOptions {
2017-09-26 13:17:47 -04:00
return func ( s ElectronScheduler ) error {
if ts == nil {
return errors . New ( "Task[] is empty." )
} else {
2018-01-30 14:12:37 -05:00
s . ( * BaseScheduler ) . tasks = ts
2017-09-26 13:17:47 -04:00
return nil
}
}
}
2018-10-04 19:24:16 -04:00
func WithWattsAsAResource ( waar bool ) SchedulerOptions {
2017-09-26 13:17:47 -04:00
return func ( s ElectronScheduler ) error {
2018-01-30 14:12:37 -05:00
s . ( * BaseScheduler ) . wattsAsAResource = waar
2017-09-26 13:17:47 -04:00
return nil
}
}
2018-10-04 19:24:16 -04:00
func WithClassMapWatts ( cmw bool ) SchedulerOptions {
2017-09-26 13:17:47 -04:00
return func ( s ElectronScheduler ) error {
2018-01-30 14:12:37 -05:00
s . ( * BaseScheduler ) . classMapWatts = cmw
2017-09-26 13:17:47 -04:00
return nil
}
}
2018-10-04 19:24:16 -04:00
func WithRecordPCP ( recordPCP * bool ) SchedulerOptions {
2017-09-26 13:17:47 -04:00
return func ( s ElectronScheduler ) error {
2018-01-30 14:12:37 -05:00
s . ( * BaseScheduler ) . RecordPCP = recordPCP
2017-09-26 13:17:47 -04:00
return nil
}
}
2018-10-04 19:24:16 -04:00
func WithShutdown ( shutdown chan struct { } ) SchedulerOptions {
2017-09-26 13:17:47 -04:00
return func ( s ElectronScheduler ) error {
if shutdown == nil {
return errors . New ( "Shutdown channel is nil." )
} else {
2018-01-30 14:12:37 -05:00
s . ( * BaseScheduler ) . Shutdown = shutdown
2017-09-26 13:17:47 -04:00
return nil
}
}
}
2018-10-04 19:24:16 -04:00
func WithDone ( done chan struct { } ) SchedulerOptions {
2017-09-26 13:17:47 -04:00
return func ( s ElectronScheduler ) error {
if done == nil {
return errors . New ( "Done channel is nil." )
} else {
2018-01-30 14:12:37 -05:00
s . ( * BaseScheduler ) . Done = done
2017-09-26 13:17:47 -04:00
return nil
}
}
}
2018-10-04 19:24:16 -04:00
func WithPCPLog ( pcpLog chan struct { } ) SchedulerOptions {
2017-09-26 13:17:47 -04:00
return func ( s ElectronScheduler ) error {
if pcpLog == nil {
return errors . New ( "PCPLog channel is nil." )
} else {
2018-01-30 14:12:37 -05:00
s . ( * BaseScheduler ) . PCPLog = pcpLog
2017-09-26 13:17:47 -04:00
return nil
}
}
}
2018-01-19 21:20:43 +00:00
2018-10-04 19:24:16 -04:00
func WithLoggingChannels ( lmt chan elekLogDef . LogMessageType , msg chan string ) SchedulerOptions {
2018-01-19 21:20:43 +00:00
return func ( s ElectronScheduler ) error {
2018-01-30 14:12:37 -05:00
s . ( * BaseScheduler ) . logMsgType = lmt
s . ( * BaseScheduler ) . logMsg = msg
2018-01-19 21:20:43 +00:00
return nil
}
}
2018-10-04 19:24:16 -04:00
func WithSchedPolSwitchEnabled ( enableSchedPolicySwitch bool , switchingCriteria string ) SchedulerOptions {
2018-01-19 21:20:43 +00:00
return func ( s ElectronScheduler ) error {
2018-01-30 14:12:37 -05:00
s . ( * BaseScheduler ) . schedPolSwitchEnabled = enableSchedPolicySwitch
2018-04-17 23:44:36 +00:00
// Checking if valid switching criteria.
if _ , ok := switchBasedOn [ switchingCriteria ] ; ! ok {
return errors . New ( "Invalid scheduling policy switching criteria." )
}
s . ( * BaseScheduler ) . schedPolSwitchCriteria = switchingCriteria
2018-01-19 21:20:43 +00:00
return nil
}
}
2018-01-26 17:29:43 -05:00
2018-10-04 19:24:16 -04:00
func WithNameOfFirstSchedPolToFix ( nameOfFirstSchedPol string ) SchedulerOptions {
2018-04-17 20:09:35 +00:00
return func ( s ElectronScheduler ) error {
if nameOfFirstSchedPol == "" {
2018-11-08 20:07:06 -05:00
log . Println ( "First scheduling policy to deploy not mentioned. This is now" +
" going to be determined at runtime." )
2018-04-17 20:09:35 +00:00
return nil
}
if _ , ok := SchedPolicies [ nameOfFirstSchedPol ] ; ! ok {
return errors . New ( "Invalid name of scheduling policy." )
}
s . ( * BaseScheduler ) . nameOfFstSchedPolToDeploy = nameOfFirstSchedPol
return nil
}
}
2018-10-04 19:24:16 -04:00
func WithFixedSchedulingWindow ( toFixSchedWindow bool , fixedSchedWindowSize int ) SchedulerOptions {
2018-04-17 20:12:33 +00:00
return func ( s ElectronScheduler ) error {
if toFixSchedWindow {
if fixedSchedWindowSize <= 0 {
return errors . New ( "Invalid value of scheduling window size. Please provide a value > 0." )
}
2018-11-08 20:07:06 -05:00
log . Println ( fmt . Sprintf ( "Fixing the size of the scheduling window to %d.." +
"." , fixedSchedWindowSize ) )
2018-04-17 20:12:33 +00:00
s . ( * BaseScheduler ) . toFixSchedWindow = toFixSchedWindow
s . ( * BaseScheduler ) . schedWindowSize = fixedSchedWindowSize
}
// There shouldn't be any error for this scheduler option.
2018-11-08 20:07:06 -05:00
// If fixSchedWindow is set to false, then the fixedSchedWindowSize would be ignored. In this case,
2018-04-17 20:12:33 +00:00
// the size of the scheduling window would be determined at runtime.
return nil
}
}
2018-02-09 17:31:16 -05:00
// Launch tasks.
func LaunchTasks ( offerIDs [ ] * mesos . OfferID , tasksToLaunch [ ] * mesos . TaskInfo , driver sched . SchedulerDriver ) {
2018-01-26 17:29:43 -05:00
driver . LaunchTasks ( offerIDs , tasksToLaunch , mesosUtils . DefaultFilter )
// Update resource availability
2018-01-29 18:19:44 -05:00
for _ , task := range tasksToLaunch {
2018-02-09 17:31:16 -05:00
utilities . ResourceAvailabilityUpdate ( "ON_TASK_ACTIVE_STATE" , * task . TaskId , * task . SlaveId )
2018-01-26 17:29:43 -05:00
}
}
2018-02-16 21:49:12 +00:00
// Sort N tasks in the TaskQueue
func SortNTasks ( tasks [ ] def . Task , n int , sb def . SortBy ) {
def . SortTasks ( tasks [ : n ] , sb )
}