Example #1
0
func (r region) communicate() {

	//collect region statistics
	ticker := time.NewTicker(5 * time.Second)

	//object holding process reference
	var exe *exec.Cmd
	exe = nil
	var start time.Time
	var proc *process.Process

	//process communication
	terminated := make(chan bool)

	for {
		select {
		case <-terminated:
			//the process exited for some Reason
			exe = nil
		case cmd := <-r.cmds:
			switch cmd.command {
			case "start":
				//if already running, exit
				if exe != nil {
					r.log.Error("Region is already running", r.UUID)
					continue
				}
				//execute binaries
				os.Chdir(r.dir)
				cmdName := "/usr/bin/mono"
				cmdArgs := []string{"OpenSim.exe", "-console", "rest"}
				exe = exec.Command(cmdName, cmdArgs...)
				err := exe.Start()
				if err != nil {
					errMsg := fmt.Sprintf("Error starting process: %s", err.Error())
					r.log.Error(errMsg)
					continue
				}
				r.log.Info("Started Successfully")
				start = time.Now()
				proc, _ = process.NewProcess(int32(exe.Process.Pid))
				go func() {
					//wait for process, ignoring process-specific errors
					_ = exe.Wait()
					r.log.Error("Terminated")
					exe = nil
					terminated <- true
				}()
			case "kill":
				//if not running, exit
				if exe == nil {
					errMsg := fmt.Sprintf("Kill region %v failed, region is not running", r.UUID.String())
					r.log.Error(errMsg)
					continue
				}
				if err := exe.Process.Kill(); err != nil {
					errMsg := fmt.Sprintf("Error killing process: %s", err.Error())
					r.log.Error(errMsg)
				}
			default:
				r.log.Info("Received unexpected command: %v", cmd.command)
			}
		case <-ticker.C:
			stat := mgm.RegionStat{UUID: r.UUID}
			if exe == nil {
				//trivially halted if we never started
				r.rStat <- stat
				continue
			}
			stat.Running = true

			cpuPercent, err := proc.CPUPercent(0)
			if err != nil {
				errMsg := fmt.Sprintf("Error getting cpu for pid: %s", err.Error())
				r.log.Error(errMsg)
			} else {
				stat.CPUPercent = cpuPercent
			}
			//memory info from this module may not be correct....
			memInfo, err := proc.MemoryInfo()
			if err != nil {
				errMsg := fmt.Sprintf("Error getting memory for pid: %s", err.Error())
				r.log.Error(errMsg)
			} else {
				stat.MemKB = (float64(memInfo.RSS) / 1024.0)
			}

			elapsed := time.Since(start)
			stat.Uptime = elapsed

			r.rStat <- stat
		}
	}
}