package consumer import ( "fmt" "os/exec" "amuz.es/src/infra/cpu_ctrl/util" "time" "amuz.es/src/infra/cpu_ctrl/processor" "amuz.es/src/infra/cpu_ctrl/logger" "bytes" ) var ( log = logger.NewLogger("consumer") ) type fanControl struct { processorCount int handler util.Handler fanSpeedConsumer chan processor.FanspeedInfo sampleDuration time.Duration } type FanControl interface { Consumer() chan<- processor.FanspeedInfo StartControl() } func NewFanControl(processorCount int, sampleDuration time.Duration, handler util.Handler) FanControl { return &fanControl{ processorCount: processorCount, handler: handler, fanSpeedConsumer: make(chan processor.FanspeedInfo, processorCount), sampleDuration: sampleDuration, } } func (c *fanControl) Consumer() chan<- processor.FanspeedInfo { return c.fanSpeedConsumer } func (c *fanControl) StartControl() { defer c.handler.DecreaseWait() defer func() { if err := recover(); err != nil { c.handler.NotifyError(err.(error)) } }() defer close(c.fanSpeedConsumer) log.Info("Fan control started") ticker := time.Tick(c.sampleDuration) fanSpeedList := make([]int, c.processorCount) for { newFanSpeedList := make([]int, c.processorCount) for { select { case <-ticker: break case changedSpeed := <-c.fanSpeedConsumer: newFanSpeedList[changedSpeed.Id] = changedSpeed.FanSpeed case <-c.handler.Done(): return } } if (!compareFanSpeed(fanSpeedList, newFanSpeedList)) { fanSpeedList = newFanSpeedList args := make([]string, 0) args = append(args, "raw", "0x3a", "0x01", ) for _, item := range fanSpeedList { args = append(args, fmt.Sprintf("0x%x", item)) } args = append(args, "0x0", "0x0", "0x0", "0x0", "0x0", "0x0", ) cmd := exec.Command("ipmitool", args...) if err := cmd.Run(); err != nil { c.handler.NotifyError(err) return } buf := bytes.NewBufferString("") for _, item := range fanSpeedList { buf.WriteString(fmt.Sprintf("0x%x", item)) buf.WriteRune(' ') } log.Infof("Commit fan speed with %s", buf.String()) } } } func compareFanSpeed(old, new []int) bool { for i, v := range old { if v != new[i] { // here is no bounds checking for b[i] return false } } return true }