From d831e7db9a12461057c2d0edb0e868b02d925035 Mon Sep 17 00:00:00 2001 From: Yinka Adedire Date: Fri, 22 Nov 2024 17:00:09 +0100 Subject: [PATCH] Add exponential backoff retry for email sending and file downloads --- go.mod | 3 ++- go.sum | 2 ++ main.go | 21 ++++++++++++++++----- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 9ccd5b0..3c71735 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,9 @@ module book-to-kindle-bot -go 1.22.4 +go 1.23.3 require ( + github.com/cenkalti/backoff/v4 v4.3.0 github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 github.com/joho/godotenv v1.5.1 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df diff --git a/go.sum b/go.sum index 37e3df9..83488bf 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc= diff --git a/main.go b/main.go index a6c127c..1f48678 100644 --- a/main.go +++ b/main.go @@ -13,6 +13,7 @@ import ( "strings" "time" + "github.com/cenkalti/backoff/v4" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" "github.com/joho/godotenv" "gopkg.in/gomail.v2" @@ -20,6 +21,7 @@ import ( ) type BotConfig struct { + MaxWorkers int DbPath string BotEmail string TelegramToken string @@ -148,9 +150,7 @@ func (b *BookToKindleBot) Start(ctx context.Context) error { updateConfig := tgbotapi.NewUpdate(0) updateConfig.Timeout = int(time.Second * 60) updates := b.telegramBotApi.GetUpdatesChan(updateConfig) - - maxWorkers := 10 - workerPool := make(chan struct{}, maxWorkers) + workerPool := make(chan struct{}, b.config.MaxWorkers) for { select { @@ -266,7 +266,11 @@ func (b *BookToKindleBot) sendEmail(kindleEmail string, fileBytes []byte, fileNa d := gomail.NewDialer("email-smtp.us-east-1.amazonaws.com", 587, os.Getenv("AWS_SES_SMTP_USERNAME"), os.Getenv("AWS_SES_SMTP_PASSWORD")) - if err := d.DialAndSend(m); err != nil { + err := backoff.Retry(func() error { + return d.DialAndSend(m) + }, backoff.NewExponentialBackOff()) + + if err != nil { return fmt.Errorf("error sending email: %w", err) } @@ -371,7 +375,13 @@ func (b *BookToKindleBot) downloadTelegramFile(fileId string) ([]byte, error) { return nil, fmt.Errorf("error getting file URL: %w", err) } - resp, err := b.httpClient.Get(fileUrl) + var resp *http.Response + err = backoff.Retry(func() error { + var err error + resp, err = b.httpClient.Get(fileUrl) + return err + }, backoff.NewExponentialBackOff()) + if err != nil { return nil, fmt.Errorf("error downloading file: %w", err) } @@ -401,6 +411,7 @@ func main() { bookToKindleBot, err := NewBookToKindleBot(BotConfig{ DownloadTimeout: 30 * time.Second, MaxFileSize: 20 * 1024 * 1024, + MaxWorkers: 10, DbPath: os.Getenv("DB_PATH"), BotEmail: os.Getenv("BOT_EMAIL"), TelegramToken: os.Getenv("TELEGRAM_BOT_TOKEN"),