|
@@ -0,0 +1,87 @@
|
|
|
+package main
|
|
|
+
|
|
|
+import (
|
|
|
+ "github.com/sirupsen/logrus"
|
|
|
+ "math/rand"
|
|
|
+ "sync/atomic"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+const (
|
|
|
+ MAX_RUN = 3
|
|
|
+ MIN_RUN = 1
|
|
|
+ TIME_CHECK = 10 * time.Second // 没十分钟检查一次
|
|
|
+)
|
|
|
+
|
|
|
+var BotQueue *queue
|
|
|
+var Working int64
|
|
|
+
|
|
|
+func init() {
|
|
|
+ BotQueue = newQueue()
|
|
|
+}
|
|
|
+
|
|
|
+func Run(bots []string) {
|
|
|
+ StringShuffle(bots)
|
|
|
+
|
|
|
+ for _, bot := range bots {
|
|
|
+ BotQueue.rPush(bot)
|
|
|
+ }
|
|
|
+ logrus.Info("bots queue init")
|
|
|
+
|
|
|
+ ticker := time.NewTicker(TIME_CHECK)
|
|
|
+ defer ticker.Stop()
|
|
|
+
|
|
|
+ botCh := make(chan string)
|
|
|
+ master(botCh)
|
|
|
+
|
|
|
+ for {
|
|
|
+ select {
|
|
|
+ case <-ticker.C:
|
|
|
+ master(botCh)
|
|
|
+
|
|
|
+ case exitBot := <-botCh:
|
|
|
+ logrus.Warnf("bot: %s exit!", exitBot)
|
|
|
+ atomic.AddInt64(&Working, -1)
|
|
|
+ BotQueue.rPush(exitBot) // 退出机器人重新加到队尾
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func master(botCh chan<- string) {
|
|
|
+ logrus.Info("check running worker")
|
|
|
+
|
|
|
+ running := atomic.LoadInt64(&Working)
|
|
|
+ logrus.Infof("running %d bots, queue len: %d", running, BotQueue.getLen())
|
|
|
+
|
|
|
+ if running <= MIN_RUN {
|
|
|
+ need := MAX_RUN - running
|
|
|
+
|
|
|
+ var i int64
|
|
|
+ for ; i < need; i++ {
|
|
|
+ bot := BotQueue.lPop()
|
|
|
+ if bot == nil {
|
|
|
+ logrus.Error("bot queue empty!!!")
|
|
|
+ break
|
|
|
+ }
|
|
|
+ go worker(bot.(string), botCh)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func worker(bot string, botCh chan<- string) {
|
|
|
+ logrus.Infof("bot: %s running~", bot)
|
|
|
+ atomic.AddInt64(&Working, 1)
|
|
|
+ for {
|
|
|
+ rand.Seed(time.Now().UnixNano())
|
|
|
+ c := rand.Intn(5)
|
|
|
+
|
|
|
+ logrus.Infof("bot: %s calc %d", bot, c)
|
|
|
+ if c == 3 {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ time.Sleep(2 * time.Second)
|
|
|
+ }
|
|
|
+
|
|
|
+ botCh <- bot
|
|
|
+}
|