package llmapi import ( "context" "gralias/broker" "gralias/models" "strconv" "sync" "time" ) type roomTimer struct { ticker *time.Ticker done chan bool } var ( timers = make(map[string]*roomTimer) mu sync.Mutex ) func (b *Bot) StartTurnTimer(timeLeft uint32) { mu.Lock() defer mu.Unlock() if _, exists := timers[b.RoomID]; exists { b.log.Debug("trying to launch already running timer", "room_id", b.RoomID) return // Timer already running } ticker := time.NewTicker(1 * time.Second) done := make(chan bool) timers[b.RoomID] = &roomTimer{ticker: ticker, done: done} go func() { for { select { case <-done: return case <-ticker.C: if timeLeft <= 0 { room, err := repo.RoomGetByID(context.Background(), b.RoomID) if err != nil { b.log.Error("failed to get room by id", "error", err) b.StopTurnTimer() return } b.log.Info("turn time is over", "room_id", b.RoomID) room.ChangeTurn() room.MimeDone = false if err := repo.RoomUpdate(context.Background(), room); err != nil { b.log.Error("failed to save room", "error", err) } broker.Notifier.Notifier <- broker.NotificationEvent{ EventName: models.NotifyTurnTimerPrefix + room.ID, Payload: strconv.FormatUint(uint64(room.Settings.RoundTime), 10), } // notifyBotIfNeeded(room) if botName := room.WhichBotToMove(); botName != "" { SignalChanMap[botName] <- true } b.StopTurnTimer() return } timeLeft-- // notify(models.NotifyTurnTimerPrefix+roomID, strconv.FormatUint(uint64(timeLeft), 10)) broker.Notifier.Notifier <- broker.NotificationEvent{ EventName: models.NotifyTurnTimerPrefix + b.RoomID, Payload: strconv.FormatUint(uint64(timeLeft), 10), } } } }() } func (b *Bot) StopTurnTimer() { mu.Lock() defer mu.Unlock() if timer, exists := timers[b.RoomID]; exists { timer.ticker.Stop() close(timer.done) delete(timers, b.RoomID) } }