示例#1
0
func main() {
	flag.Parse()

	//make the out dir
	logger.Component = "SIMULATOR"
	if outDir == "" {
		logger.Fatal("out.dir.unspecified")
	}
	err := os.MkdirAll(outDir, 0777)
	if err != nil {
		logger.Fatal("out.dir.creation.failed", err)
	}

	//set up logging
	outputFile, err := os.Create(filepath.Join(outDir, "simulator.log"))
	if err != nil {
		logger.Fatal("failed.to.create.simulator.log", err)
	}
	logger.Writer = io.MultiWriter(os.Stdout, outputFile)
	cleanup.Register(func() {
		outputFile.Sync()
	})

	//compile the executor
	logger.Info("compiling.executor")
	output, err := exec.Command("go", "install", "github.com/cloudfoundry-incubator/simulator/game_executor").CombinedOutput()
	if err != nil {
		logger.Fatal("failed.to.compile.executor", string(output))
	}

	//write info to the output dir
	writeInfo()

	//start etcd
	logger.Info("starting.etcd", etcdNodes)
	etcd = etcdstorerunner.NewETCDClusterRunner(4001, etcdNodes)
	etcd.Start()

	//set up the bbs
	pool := workerpool.NewWorkerPool(50)
	etcdAdapter = etcdstoreadapter.NewETCDStoreAdapter(etcd.NodeURLS(), pool)
	etcdAdapter.Connect()
	bbs = Bbs.New(etcdAdapter, timeprovider.NewTimeProvider())

	//monitor etcd
	monitorETCD()

	//start executors
	startExecutors()

	cleanup.Register(func() {
		logger.Info("stopping.etcd", etcdNodes)
		etcd.Stop()
	})

	//run the simulator
	runSimulation()

	cleanup.Exit(0)
}
示例#2
0
func sleepForRunInterval() {
	runSleep := strings.Split(*runSleepRange, ",")
	minRunSleep, err := strconv.Atoi(runSleep[0])
	if err != nil {
		logger.Fatal("run.sleep.min.parse.fatal", err)
	}
	maxRunSleep, err := strconv.Atoi(runSleep[1])
	if err != nil {
		logger.Fatal("run.sleep.min.parse.fatal", err)
	}
	sleepForARandomInterval("sleep.run", minRunSleep, maxRunSleep)
}
示例#3
0
func sleepForContainerCreationInterval() {
	containerCreationSleep := strings.Split(*containerCreationSleepRange, ",")
	minContainerCreationSleep, err := strconv.Atoi(containerCreationSleep[0])
	if err != nil {
		logger.Fatal("container.creation.sleep.min.parse.fatal", err)
	}
	maxContainerCreationSleep, err := strconv.Atoi(containerCreationSleep[1])
	if err != nil {
		logger.Fatal("container.creation.sleep.min.parse.fatal", err)
	}
	sleepForARandomInterval("sleep.create", minContainerCreationSleep, maxContainerCreationSleep)
}
示例#4
0
func convergeRunOnces(bbs Bbs.ExecutorBBS) {
	statusChannel, releaseLock, err := bbs.MaintainConvergeLock(*convergenceInterval, *executorID)
	if err != nil {
		logger.Fatal("executor.converge-lock.acquire-failed", err)
	}

	tasks.Add(1)

	for {
		select {
		case locked, ok := <-statusChannel:
			if !ok {
				tasks.Done()
				return
			}

			if locked {
				t := time.Now()
				logger.Info("converging")
				bbs.ConvergeRunOnce(*timeToClaimRunOnce)
				logger.Info("converged", time.Since(t))
			} else {
				logger.Error("lost.convergence.lock")
			}
		case <-stop:
			releaseLock <- nil
		}
	}
}
示例#5
0
func main() {
	flag.Parse()
	cleanup.Register(func() {
		logger.Info("executor.shuttingdown")
		close(stop)
		tasks.Wait()
		logger.Info("executor.shutdown")
	})
	logger.Component = fmt.Sprintf("EXECUTOR %s", *executorID)

	lock = &sync.Mutex{}
	currentMemory = *maxMemory

	etcdAdapter := etcdstoreadapter.NewETCDStoreAdapter(
		strings.Split(*etcdCluster, ","),
		workerpool.NewWorkerPool(10),
	)
	err := etcdAdapter.Connect()
	if err != nil {
		logger.Fatal("etcd.connect.fatal", err)
	}

	tasks = &sync.WaitGroup{}
	stop = make(chan bool)

	bbs := Bbs.New(etcdAdapter, timeprovider.NewTimeProvider())

	ready := make(chan bool, 1)

	err = maintainPresence(bbs, ready)
	if err != nil {
		logger.Fatal("executor.initializing-presence.failed", err)
	}

	go handleRunOnces(bbs)
	go convergeRunOnces(bbs)

	<-ready

	logger.Info("executor.up")

	select {}
}
示例#6
0
func monitorETCD() {
	outputFile, err := os.Create(filepath.Join(outDir, "etcdstats.log"))
	if err != nil {
		logger.Fatal("etcd.log.creation.failure", err)
	}
	cleanup.Register(func() {
		outputFile.Sync()
	})

	go monitorRunOnces(outputFile)
}
示例#7
0
func startExecutors() {
	executorOutput, err := os.Create(filepath.Join(outDir, "executors.log"))
	if err != nil {
		logger.Fatal("executor.output.file.create.failed", err)
	}
	cleanup.Register(func() {
		executorOutput.Sync()
	})

	logger.Info("starting.all.executors", nExecutors)
	allExecutorsStarted := &sync.WaitGroup{}
	for index := 1; index <= nExecutors; index++ {
		allExecutorsStarted.Add(1)
		go startAndMonitorExecutor(index, executorOutput, allExecutorsStarted)
	}
	allExecutorsStarted.Wait()
	logger.Info("started.all.executors", nExecutors)
}
示例#8
0
func maintainPresence(bbs Bbs.ExecutorBBS, ready chan<- bool) error {
	p, statusChannel, err := bbs.MaintainExecutorPresence(*heartbeatInterval, *executorID)
	if err != nil {
		ready <- false
		return err
	}

	tasks.Add(1)

	go func() {
		for {
			select {
			case locked, ok := <-statusChannel:
				if locked && ready != nil {
					ready <- true
					ready = nil
				}

				if !locked && ok {
					tasks.Done()
					logger.Fatal("maintain.presence.fatal", err)
				}

				if !ok {
					tasks.Done()
					return
				}

			case <-stop:
				p.Remove()
				tasks.Done()
			}
		}
	}()

	return nil
}