X-Git-Url: https://git.giacomolli.uk/onechat/blobdiff_plain/b2fc2d6a737dd5bab25e57ba822dd07258de93e6..48d7bce28b18ecef4c52c98821675605464cecb9:/telegram.go diff --git a/telegram.go b/telegram.go index a595b68..f3b3bb2 100644 --- a/telegram.go +++ b/telegram.go @@ -18,6 +18,14 @@ import ( ) const ( + // telegramRetryDelay is the wait before the first retry of a failed + // call. + telegramRetryDelay = time.Second + + // telegramRetryLimit is the longest wait between retries of a failed + // call. + telegramRetryLimit = time.Minute + // telegramAPIURL is the Telegram Bot API service. telegramAPIURL = "https://api.telegram.org" @@ -103,8 +111,6 @@ func newTelegramBot(api *TelegramAPI, owner int64, offsetPath string, logger *sl owner: owner, offsetPath: offsetPath, logger: logger, - minWait: time.Second, - maxWait: time.Minute, ready: make(chan struct{}, 1), } } @@ -146,17 +152,15 @@ func (c TelegramConfig) validate() error { // does not lose a message. A crash between the flush and the offset write // makes Telegram send the update again, and the message repeats once. // -// A failed Bot API call waits and tries again, from minWait up to maxWait, or -// as long as the Bot API asks. It never stops the agent. A TelegramOutage logs -// the first failure and the end of each run of failures, and the retries -// between them log nothing. +// A failed Bot API call waits and tries again, from telegramRetryDelay up to +// telegramRetryLimit, or as long as the Bot API asks. It never stops the agent. +// A TelegramOutage logs the first failure and the end of each run of failures, +// and the retries between them log nothing. type TelegramBot struct { api *TelegramAPI owner int64 offsetPath string logger *slog.Logger - minWait time.Duration - maxWait time.Duration mutex sync.Mutex queue []Event @@ -279,8 +283,8 @@ func (b *TelegramBot) poll(ctx context.Context, l *TurnLoop, whatsapp *WhatsApp) back: "image receive back", } - imageWait := b.minWait - wait := b.minWait + imageWait := telegramRetryDelay + wait := telegramRetryDelay poll: for ctx.Err() == nil { @@ -298,7 +302,7 @@ poll: outage.End() - wait = b.minWait + wait = telegramRetryDelay for _, update := range updates { if ctx.Err() != nil { @@ -318,7 +322,7 @@ poll: imageOutage.End() - imageWait = b.minWait + imageWait = telegramRetryDelay offset = update.UpdateID + 1 err = telegramSaveOffset(b.offsetPath, offset) @@ -373,7 +377,8 @@ func (b *TelegramBot) post(ctx context.Context, event Event) { } // pause gives err to outage and waits the longer of wait and asked, or until -// ctx ends. It returns the wait of the next failure: twice wait, up to maxWait. +// ctx ends. It returns the wait of the next failure: twice wait, up to +// telegramRetryLimit. func (b *TelegramBot) pause(ctx context.Context, outage *TelegramOutage, err error, wait, asked time.Duration) time.Duration { delay := max(wait, asked) outage.Fail(err, delay) @@ -386,7 +391,7 @@ func (b *TelegramBot) pause(ctx context.Context, outage *TelegramOutage, err err case <-ctx.Done(): } - return min(2*wait, b.maxWait) + return min(2*wait, telegramRetryLimit) } // handle runs one update. A text message of the owner in the private chat goes @@ -480,7 +485,7 @@ func (b *TelegramBot) handle(ctx context.Context, l *TurnLoop, whatsapp *WhatsAp // later try can fix, until ctx ends. It drops the part after any other failure. func (b *TelegramBot) deliver(ctx context.Context, part TelegramPart) { outage := b.sendOutage() - wait := b.minWait + wait := telegramRetryDelay for { err := b.api.SendMessage(ctx, b.owner, part.text, part.entities) retry, asked := telegramRetryable(err) @@ -521,7 +526,7 @@ func (b *TelegramBot) deliver(ctx context.Context, part TelegramPart) { // fix, until ctx ends. It drops the message after any other failure. func (b *TelegramBot) deliverRich(ctx context.Context, markdown string) { outage := b.sendOutage() - wait := b.minWait + wait := telegramRetryDelay for { err := b.api.SendRichMessage(ctx, b.owner, markdown) retry, asked := telegramRetryable(err)