2016-09-08 02:06:24 -04:00
package main
import (
2016-11-10 19:49:39 -05:00
"bitbucket.org/sunybingcloud/electron/def"
2016-11-14 22:42:22 -05:00
"bitbucket.org/sunybingcloud/electron/pcp"
2017-01-03 20:57:25 -05:00
"bitbucket.org/sunybingcloud/electron/schedulers"
2016-09-08 02:06:24 -04:00
"flag"
"fmt"
"github.com/golang/protobuf/proto"
mesos "github.com/mesos/mesos-go/mesosproto"
sched "github.com/mesos/mesos-go/scheduler"
"log"
"os"
2016-10-07 20:47:59 -04:00
"os/signal"
2016-10-13 17:15:09 -04:00
"time"
2016-09-08 02:06:24 -04:00
)
2016-09-27 18:12:50 -04:00
var master = flag . String ( "master" , "xavier:5050" , "Location of leading Mesos master" )
var tasksFile = flag . String ( "workload" , "" , "JSON file containing task definitions" )
2016-09-27 19:15:32 -04:00
var ignoreWatts = flag . Bool ( "ignoreWatts" , false , "Ignore watts in offers" )
2016-09-27 20:22:07 -04:00
var pcplogPrefix = flag . String ( "logPrefix" , "" , "Prefix for pcplog" )
2016-10-18 17:38:49 -04:00
var hiThreshold = flag . Float64 ( "hiThreshold" , 0.0 , "Upperbound for when we should start capping" )
var loThreshold = flag . Float64 ( "loThreshold" , 0.0 , "Lowerbound for when we should start uncapping" )
2016-09-27 18:12:50 -04:00
// Short hand args
2016-10-13 17:15:09 -04:00
func init ( ) {
2016-09-27 19:15:32 -04:00
flag . StringVar ( master , "m" , "xavier:5050" , "Location of leading Mesos master (shorthand)" )
flag . StringVar ( tasksFile , "w" , "" , "JSON file containing task definitions (shorthand)" )
flag . BoolVar ( ignoreWatts , "i" , false , "Ignore watts in offers (shorthand)" )
2016-10-13 17:15:09 -04:00
flag . StringVar ( pcplogPrefix , "p" , "" , "Prefix for pcplog (shorthand)" )
2016-10-18 17:38:49 -04:00
flag . Float64Var ( hiThreshold , "ht" , 700.0 , "Upperbound for when we should start capping (shorthand)" )
flag . Float64Var ( loThreshold , "lt" , 400.0 , "Lowerbound for when we should start uncapping (shorthand)" )
2016-09-27 18:12:50 -04:00
}
2016-09-08 02:06:24 -04:00
func main ( ) {
flag . Parse ( )
2016-09-16 19:06:53 -04:00
if * tasksFile == "" {
fmt . Println ( "No file containing tasks specifiction provided." )
os . Exit ( 1 )
}
2016-10-18 17:38:49 -04:00
if * hiThreshold < * loThreshold {
fmt . Println ( "High threshold is of a lower value than low threhold." )
os . Exit ( 1 )
}
2016-10-13 17:15:09 -04:00
tasks , err := def . TasksFromJSON ( * tasksFile )
if err != nil || len ( tasks ) == 0 {
2016-09-16 19:06:53 -04:00
fmt . Println ( "Invalid tasks specification file provided" )
os . Exit ( 1 )
}
2016-09-17 18:55:35 -04:00
log . Println ( "Scheduling the following tasks:" )
for _ , task := range tasks {
fmt . Println ( task )
}
2017-01-03 20:30:21 -05:00
startTime := time . Now ( ) . Format ( "20060102150405" )
logPrefix := * pcplogPrefix + "_" + startTime
2016-09-17 18:55:35 -04:00
2017-01-15 15:23:57 -05:00
scheduler := schedulers . NewFirstFitSortedWattsReducedWAR ( tasks , * ignoreWatts , logPrefix )
2016-09-08 02:06:24 -04:00
driver , err := sched . NewMesosSchedulerDriver ( sched . DriverConfig {
Master : * master ,
Framework : & mesos . FrameworkInfo {
2016-09-15 15:53:56 -04:00
Name : proto . String ( "Electron" ) ,
2016-09-08 02:06:24 -04:00
User : proto . String ( "" ) ,
} ,
Scheduler : scheduler ,
} )
if err != nil {
log . Printf ( "Unable to create scheduler driver: %s" , err )
return
}
2017-01-15 15:23:57 -05:00
//go pcp.Start(scheduler.PCPLog, &scheduler.RecordPCP, logPrefix)
go pcp . StartPCPLogAndExtremaDynamicCap ( scheduler . PCPLog , & scheduler . RecordPCP , logPrefix , * hiThreshold , * loThreshold )
2017-01-04 20:25:54 -05:00
time . Sleep ( 1 * time . Second ) // Take a second between starting PCP log and continuing
2016-09-26 19:14:51 -04:00
2016-10-07 20:47:59 -04:00
// Attempt to handle signint to not leave pmdumptext running
2016-09-08 02:06:24 -04:00
// Catch interrupt
2016-10-07 20:47:59 -04:00
go func ( ) {
c := make ( chan os . Signal , 1 )
signal . Notify ( c , os . Interrupt , os . Kill )
s := <- c
if s != os . Interrupt {
2016-10-13 17:15:09 -04:00
close ( scheduler . PCPLog )
2016-10-07 20:47:59 -04:00
return
}
log . Printf ( "Received SIGINT...stopping" )
2016-10-13 17:15:09 -04:00
close ( scheduler . Done )
2016-10-07 20:47:59 -04:00
} ( )
2016-09-08 02:06:24 -04:00
go func ( ) {
2016-09-26 19:14:51 -04:00
// Signals we have scheduled every task we have
2016-09-19 20:25:10 -04:00
select {
2016-10-13 17:15:09 -04:00
case <- scheduler . Shutdown :
// case <-time.After(shutdownTimeout):
2016-09-17 18:55:35 -04:00
}
2016-09-08 02:06:24 -04:00
2016-10-07 20:47:59 -04:00
// All tasks have finished
2016-09-08 02:06:24 -04:00
select {
2016-10-13 17:15:09 -04:00
case <- scheduler . Done :
close ( scheduler . PCPLog )
2016-09-26 19:14:51 -04:00
time . Sleep ( 5 * time . Second ) //Wait for PCP to log a few more seconds
2016-10-13 17:15:09 -04:00
// case <-time.After(shutdownTimeout):
2016-09-08 02:06:24 -04:00
}
// Done shutting down
driver . Stop ( false )
2016-09-17 18:55:35 -04:00
2016-09-08 02:06:24 -04:00
} ( )
2016-09-15 15:53:56 -04:00
log . Printf ( "Starting..." )
2016-09-08 02:06:24 -04:00
if status , err := driver . Run ( ) ; err != nil {
log . Printf ( "Framework stopped with status %s and error: %s\n" , status . String ( ) , err . Error ( ) )
}
log . Println ( "Exiting..." )
}