Reorganized code.
Building the scheduler in phases. To be able to do this, increased visibility of schedulers/helpers.go#schedulerOptions. Refactored dependent code.
This commit is contained in:
parent
c9d4e66236
commit
4637355721
5 changed files with 110 additions and 91 deletions
167
scheduler.go
167
scheduler.go
|
@ -15,8 +15,8 @@ import (
|
|||
"gitlab.com/spdf/elektron/def"
|
||||
elekLogDef "gitlab.com/spdf/elektron/logging/def"
|
||||
"gitlab.com/spdf/elektron/pcp"
|
||||
"gitlab.com/spdf/elektron/schedulers"
|
||||
"gitlab.com/spdf/elektron/powerCap"
|
||||
"gitlab.com/spdf/elektron/schedulers"
|
||||
)
|
||||
|
||||
var master = flag.String("master", "", "Location of leading Mesos master -- <mesos-master>:<port>")
|
||||
|
@ -71,12 +71,13 @@ func listAllSchedulingPolicies() {
|
|||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
// checking to see if we need to just list the pluggable scheduling policies
|
||||
// Checking to see if we need to just list the pluggable scheduling policies
|
||||
if *listSchedPolicies {
|
||||
listAllSchedulingPolicies()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Creating logger and attaching different logging platforms.
|
||||
startTime := time.Now()
|
||||
formattedStartTime := startTime.Format("20060102150405")
|
||||
// Checking if prefix contains any special characters
|
||||
|
@ -84,16 +85,18 @@ func main() {
|
|||
log.Fatal("log file prefix should not contain '/'.")
|
||||
}
|
||||
logPrefix := *pcplogPrefix + "_" + formattedStartTime
|
||||
|
||||
// creating logger and attaching different logging platforms
|
||||
logger := elekLogDef.BuildLogger(startTime, logPrefix)
|
||||
// logging channels
|
||||
// Logging channels.
|
||||
logMType := make(chan elekLogDef.LogMessageType)
|
||||
logMsg := make(chan string)
|
||||
go logger.Listen(logMType, logMsg)
|
||||
|
||||
// If non-default scheduling policy given,
|
||||
// checking if scheduling policyName exists
|
||||
// First we need to build the scheduler using scheduler options.
|
||||
var schedOptions []schedulers.SchedulerOptions = make([]schedulers.SchedulerOptions, 0, 10)
|
||||
|
||||
// OPTIONAL PARAMETERS
|
||||
// Scheduling Policy Name
|
||||
// If non-default scheduling policy given, checking if name exists.
|
||||
if *schedPolicyName != "first-fit" {
|
||||
if _, ok := schedulers.SchedPolicies[*schedPolicyName]; !ok {
|
||||
// invalid scheduling policy
|
||||
|
@ -103,68 +106,54 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
if *tasksFile == "" {
|
||||
//fmt.Println("No file containing tasks specifiction provided.")
|
||||
logger.WriteLog(elekLogDef.ERROR, "No file containing tasks specification provided")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if *hiThreshold < *loThreshold {
|
||||
//fmt.Println("High threshold is of a lower value than low threshold.")
|
||||
logger.WriteLog(elekLogDef.ERROR, "High threshold is of a lower value than low threshold")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
tasks, err := def.TasksFromJSON(*tasksFile)
|
||||
if err != nil || len(tasks) == 0 {
|
||||
//fmt.Println("Invalid tasks specification file provided")
|
||||
logger.WriteLog(elekLogDef.ERROR, "Invalid tasks specification file provided")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
//log.Println("Scheduling the following tasks:")
|
||||
logger.WriteLog(elekLogDef.GENERAL, "Scheduling the following tasks:")
|
||||
for _, task := range tasks {
|
||||
fmt.Println(task)
|
||||
}
|
||||
|
||||
if *enableSchedPolicySwitch {
|
||||
if spcf := *schedPolConfigFile; spcf == "" {
|
||||
logger.WriteLog(elekLogDef.ERROR, "No file containing characteristics for scheduling policies")
|
||||
} else {
|
||||
// Initializing the characteristics of the scheduling policies.
|
||||
schedulers.InitSchedPolicyCharacteristics(spcf)
|
||||
}
|
||||
}
|
||||
|
||||
// CHANNELS AND FLAGS.
|
||||
shutdown := make(chan struct{})
|
||||
done := make(chan struct{})
|
||||
pcpLog := make(chan struct{})
|
||||
recordPCP := false
|
||||
scheduler := schedulers.SchedFactory(
|
||||
schedulers.WithSchedPolicy(*schedPolicyName),
|
||||
schedulers.WithTasks(tasks),
|
||||
schedulers.WithWattsAsAResource(*wattsAsAResource),
|
||||
schedulers.WithClassMapWatts(*classMapWatts),
|
||||
schedulers.WithRecordPCP(&recordPCP),
|
||||
schedulers.WithShutdown(shutdown),
|
||||
schedulers.WithDone(done),
|
||||
schedulers.WithPCPLog(pcpLog),
|
||||
schedulers.WithLoggingChannels(logMType, logMsg),
|
||||
schedulers.WithSchedPolSwitchEnabled(*enableSchedPolicySwitch, *schedPolSwitchCriteria),
|
||||
schedulers.WithNameOfFirstSchedPolToFix(*fixFirstSchedPol),
|
||||
schedulers.WithFixedSchedulingWindow(*fixSchedWindow, *schedWindowSize))
|
||||
driver, err := sched.NewMesosSchedulerDriver(sched.DriverConfig{
|
||||
Master: *master,
|
||||
Framework: &mesos.FrameworkInfo{
|
||||
Name: proto.String("Elektron"),
|
||||
User: proto.String(""),
|
||||
},
|
||||
Scheduler: scheduler,
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("Unable to create scheduler driver: %s", err)
|
||||
return
|
||||
|
||||
// Logging channels.
|
||||
// These channels are used by the framework to log messages.
|
||||
// The channels are used to send the type of log message and the message string.
|
||||
schedOptions = append(schedOptions, schedulers.WithLoggingChannels(logMType, logMsg))
|
||||
|
||||
// Shutdown indicator channels.
|
||||
// These channels are used to notify,
|
||||
// 1. scheduling is complete.
|
||||
// 2. all scheduled tasks have completed execution and framework can shutdown.
|
||||
schedOptions = append(schedOptions, schedulers.WithShutdown(shutdown))
|
||||
schedOptions = append(schedOptions, schedulers.WithDone(done))
|
||||
|
||||
// If here, then valid scheduling policy name provided.
|
||||
schedOptions = append(schedOptions, schedulers.WithSchedPolicy(*schedPolicyName))
|
||||
|
||||
// Scheduling Policy Switching.
|
||||
if *enableSchedPolicySwitch {
|
||||
// Scheduling policy config file required.
|
||||
if spcf := *schedPolConfigFile; spcf == "" {
|
||||
logger.WriteLog(elekLogDef.ERROR, "No file containing characteristics for"+
|
||||
" scheduling policies")
|
||||
os.Exit(1)
|
||||
} else {
|
||||
// Initializing the characteristics of the scheduling policies.
|
||||
schedulers.InitSchedPolicyCharacteristics(spcf)
|
||||
schedOptions = append(schedOptions, schedulers.WithSchedPolSwitchEnabled(*enableSchedPolicySwitch, *schedPolSwitchCriteria))
|
||||
// Fix First Scheduling Policy.
|
||||
schedOptions = append(schedOptions, schedulers.WithNameOfFirstSchedPolToFix(*fixFirstSchedPol))
|
||||
// Fix Scheduling Window.
|
||||
schedOptions = append(schedOptions, schedulers.WithFixedSchedulingWindow(*fixSchedWindow, *schedWindowSize))
|
||||
}
|
||||
}
|
||||
|
||||
// Watts as a Resource (WaaR) and ClassMapWatts (CMW).
|
||||
// If WaaR and CMW is enabled then for each task the class_to_watts mapping is used to
|
||||
// fit tasks into offers.
|
||||
// If CMW is disabled, then the Median of Medians Max Peak Power Usage value is used
|
||||
// as the watts value for each task.
|
||||
if *wattsAsAResource {
|
||||
logger.WriteLog(elekLogDef.GENERAL, "WaaR enabled...")
|
||||
schedOptions = append(schedOptions, schedulers.WithWattsAsAResource(*wattsAsAResource))
|
||||
schedOptions = append(schedOptions, schedulers.WithClassMapWatts(*classMapWatts))
|
||||
}
|
||||
// REQUIRED PARAMETERS.
|
||||
// PCP logging, Power capping and High and Low thresholds.
|
||||
|
@ -204,12 +193,40 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
// Checking if pcp config file exists.
|
||||
if _, err := os.Stat(*pcpConfigFile); os.IsNotExist(err) {
|
||||
logger.WriteLog(elekLogDef.ERROR, "PCP config file does not exist!")
|
||||
// Tasks
|
||||
// If httpServer is disabled, then path of file containing workload needs to be provided.
|
||||
if *tasksFile == "" {
|
||||
logger.WriteLog(elekLogDef.ERROR, "No file containing tasks specification"+
|
||||
" provided.")
|
||||
os.Exit(1)
|
||||
}
|
||||
tasks, err := def.TasksFromJSON(*tasksFile)
|
||||
if err != nil || len(tasks) == 0 {
|
||||
logger.WriteLog(elekLogDef.ERROR, "Invalid tasks specification file "+
|
||||
"provided.")
|
||||
os.Exit(1)
|
||||
}
|
||||
schedOptions = append(schedOptions, schedulers.WithTasks(tasks))
|
||||
|
||||
// Scheduler.
|
||||
scheduler := schedulers.SchedFactory(schedOptions...)
|
||||
|
||||
// Scheduler driver.
|
||||
driver, err := sched.NewMesosSchedulerDriver(sched.DriverConfig{
|
||||
Master: *master,
|
||||
Framework: &mesos.FrameworkInfo{
|
||||
Name: proto.String("Elektron"),
|
||||
User: proto.String(""),
|
||||
},
|
||||
Scheduler: scheduler,
|
||||
})
|
||||
if err != nil {
|
||||
logger.WriteLog(elekLogDef.ERROR, fmt.Sprintf("Unable to create scheduler driver:"+
|
||||
" %s", err))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Starting PCP logging.
|
||||
if noPowercap {
|
||||
go pcp.Start(pcpLog, &recordPCP, logMType, logMsg, *pcpConfigFile, scheduler)
|
||||
} else if extrema {
|
||||
|
@ -220,7 +237,8 @@ func main() {
|
|||
*loThreshold, logMType, logMsg, *pcpConfigFile)
|
||||
}
|
||||
|
||||
time.Sleep(1 * time.Second) // Take a second between starting PCP log and continuing
|
||||
// Take a second between starting PCP log and continuing.
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
// Attempt to handle SIGINT to not leave pmdumptext running.
|
||||
// Catch interrupt.
|
||||
|
@ -233,34 +251,35 @@ func main() {
|
|||
return
|
||||
}
|
||||
|
||||
log.Println("Received SIGINT...stopping")
|
||||
log.Println("Received SIGINT... stopping")
|
||||
close(done)
|
||||
}()
|
||||
|
||||
go func() {
|
||||
|
||||
// Signals we have scheduled every task we have.
|
||||
// Signals we have scheduled every task we have
|
||||
select {
|
||||
case <-shutdown:
|
||||
//case <-time.After(shutdownTimeout):
|
||||
}
|
||||
|
||||
// All tasks have finished.
|
||||
// All tasks have finished
|
||||
select {
|
||||
case <-done:
|
||||
close(pcpLog)
|
||||
time.Sleep(5 * time.Second) //Wait for PCP to log a few more seconds
|
||||
// Closing logging channels.
|
||||
close(logMType)
|
||||
close(logMsg)
|
||||
//case <-time.After(shutdownTimeout):
|
||||
}
|
||||
|
||||
// Done shutting down.
|
||||
// Done shutting down
|
||||
driver.Stop(false)
|
||||
|
||||
}()
|
||||
|
||||
log.Println("Starting...")
|
||||
// Starting the scheduler driver.
|
||||
if status, err := driver.Run(); err != nil {
|
||||
log.Printf("Framework stopped with status %s and error: %s\n", status.String(), err.Error())
|
||||
}
|
||||
|
|
Reference in a new issue