Fix tg bot graceful shutdown
This commit is contained in:
@@ -5,7 +5,6 @@ import (
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -15,14 +14,27 @@ import (
|
||||
)
|
||||
|
||||
type TelegramController struct {
|
||||
// deps
|
||||
bot *tgbotapi.BotAPI
|
||||
transcribeService *service.TranscribeService
|
||||
jobRepo contract.TranscriptJobRepository
|
||||
logger *slog.Logger
|
||||
// params
|
||||
updateTimeout int
|
||||
}
|
||||
|
||||
func NewTelegramController(transcribeService *service.TranscribeService, jobRepo contract.TranscriptJobRepository, logger *slog.Logger) (*TelegramController, error) {
|
||||
botToken := os.Getenv("TELEGRAM_BOT_TOKEN")
|
||||
type TelegramConfig struct {
|
||||
BotToken string
|
||||
UpdateTimeout int
|
||||
}
|
||||
|
||||
func NewTelegramController(
|
||||
config TelegramConfig,
|
||||
transcribeService *service.TranscribeService,
|
||||
jobRepo contract.TranscriptJobRepository,
|
||||
logger *slog.Logger,
|
||||
) (*TelegramController, error) {
|
||||
botToken := config.BotToken
|
||||
if botToken == "" {
|
||||
return nil, &EmptyBotTokenError{}
|
||||
}
|
||||
@@ -37,6 +49,7 @@ func NewTelegramController(transcribeService *service.TranscribeService, jobRepo
|
||||
transcribeService: transcribeService,
|
||||
jobRepo: jobRepo,
|
||||
logger: logger,
|
||||
updateTimeout: config.UpdateTimeout,
|
||||
}
|
||||
|
||||
return controller, nil
|
||||
@@ -46,7 +59,7 @@ func (c *TelegramController) Start() {
|
||||
c.logger.Info("Telegram bot started", "username", c.bot.Self.UserName)
|
||||
|
||||
u := tgbotapi.NewUpdate(0)
|
||||
u.Timeout = 60
|
||||
u.Timeout = c.updateTimeout
|
||||
|
||||
updates := c.bot.GetUpdatesChan(u)
|
||||
|
||||
@@ -79,7 +92,7 @@ func (c *TelegramController) Start() {
|
||||
}
|
||||
|
||||
func (c *TelegramController) Stop() {
|
||||
c.logger.Info("Telegram bot stopped")
|
||||
c.bot.StopReceivingUpdates()
|
||||
}
|
||||
|
||||
func (c *TelegramController) handleStartCommand(message *tgbotapi.Message) {
|
||||
|
29
main.go
29
main.go
@@ -30,6 +30,13 @@ import (
|
||||
sloggin "github.com/samber/slog-gin"
|
||||
)
|
||||
|
||||
const (
|
||||
TelegramUpdateTimeout = 10
|
||||
ServerShutdownTimeout = 5
|
||||
|
||||
ForceShutdownTimeout = 20
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Создаем структурированный логгер
|
||||
logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
|
||||
@@ -101,8 +108,13 @@ func main() {
|
||||
// Создаем WaitGroup для ожидания завершения всех воркеров
|
||||
var wg sync.WaitGroup
|
||||
|
||||
tgConfig := tgcontroller.TelegramConfig{
|
||||
BotToken: os.Getenv("TELEGRAM_BOT_TOKEN"),
|
||||
UpdateTimeout: TelegramUpdateTimeout,
|
||||
}
|
||||
|
||||
// Создаем Telegram бот
|
||||
tgController, err := tgcontroller.NewTelegramController(transcribeService, jobRepo, logger)
|
||||
tgController, err := tgcontroller.NewTelegramController(tgConfig, transcribeService, jobRepo, logger)
|
||||
if err != nil {
|
||||
logger.Error("Failed to create Telegram controller", "error", err)
|
||||
// Не останавливаем приложение, если Telegram бот не создан
|
||||
@@ -113,10 +125,8 @@ func main() {
|
||||
defer wg.Done()
|
||||
logger.Info("Starting Telegram bot")
|
||||
tgController.Start()
|
||||
logger.Info("Telegram bot stopped")
|
||||
}()
|
||||
|
||||
// Добавляем функцию остановки бота в контекст завершения
|
||||
defer tgController.Stop()
|
||||
}
|
||||
|
||||
// Создаем воркеры
|
||||
@@ -198,8 +208,13 @@ func main() {
|
||||
<-sigChan
|
||||
logger.Info("Received shutdown signal, initiating graceful shutdown...")
|
||||
|
||||
if tgController != nil {
|
||||
logger.Info("Shutting down Telegram bot...")
|
||||
tgController.Stop()
|
||||
}
|
||||
|
||||
// Создаем контекст с таймаутом для graceful shutdown HTTP сервера
|
||||
shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), ServerShutdownTimeout*time.Second)
|
||||
defer shutdownCancel()
|
||||
|
||||
// Останавливаем HTTP сервер
|
||||
@@ -220,11 +235,11 @@ func main() {
|
||||
close(done)
|
||||
}()
|
||||
|
||||
// Ждем завершения всех воркеров или таймаута в 10 секунд
|
||||
// Ждем завершения всех воркеров или таймаута
|
||||
select {
|
||||
case <-done:
|
||||
logger.Info("All workers stopped gracefully")
|
||||
case <-time.After(10 * time.Second):
|
||||
case <-time.After(ForceShutdownTimeout * time.Second):
|
||||
logger.Warn("Timeout reached, forcing shutdown")
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user