diff --git a/internal/mtproto/options.go b/internal/mtproto/options.go index 5b98bc9af4..70c66ff68b 100644 --- a/internal/mtproto/options.go +++ b/internal/mtproto/options.go @@ -131,10 +131,10 @@ func (opt *Options) setDefaults() { opt.SaltFetchInterval = 1 * time.Hour } if opt.PingTimeout == 0 { - opt.PingTimeout = 15 * time.Second + opt.PingTimeout = 10 * time.Second } if opt.PingInterval == 0 { - opt.PingInterval = 1 * time.Minute + opt.PingInterval = 15 * time.Second } if opt.RequestTimeout == nil { opt.RequestTimeout = func(req uint32) time.Duration { diff --git a/telegram/connect.go b/telegram/connect.go index 8f7d0f0918..f045f2718a 100644 --- a/telegram/connect.go +++ b/telegram/connect.go @@ -22,7 +22,8 @@ func (c *Client) runUntilRestart(ctx context.Context) error { if !c.noUpdatesMode { g.Go(func(ctx context.Context) error { // Call method which requires authorization, to subscribe for updates. - // See https://core.telegram.org/api/updates#subscribing-to-updates. + // See https://core.telegram.org/api/updates#subscribing-to-updates + c.log.Debug("Calling c.Self to subscribe for updates") self, err := c.Self(ctx) if err != nil { // Ignore unauthorized errors. @@ -58,21 +59,29 @@ func (c *Client) isPermanentError(err error) bool { } func (c *Client) reconnectUntilClosed(ctx context.Context) error { - // Note that we currently have no timeout on connection, so this is - // potentially eternal. b := tdsync.SyncBackoff(backoff.WithContext(c.connBackoff(), ctx)) return backoff.RetryNotify(func() error { if err := c.runUntilRestart(ctx); err != nil { + if ctxErr := ctx.Err(); ctxErr != nil { + c.log.Error("Stopping reconnection attempts due to parent context error", + zap.Error(err), + zap.Errors("error_parent", []error{ctxErr}), + ) + return errors.Wrap(err, "parent context closed") + } if c.isPermanentError(err) { return backoff.Permanent(err) } - return err + return errors.Wrap(err, "runUntilRestart") } return nil }, b, func(err error, timeout time.Duration) { - c.log.Info("Restarting connection", zap.Error(err), zap.Duration("backoff", timeout)) + c.log.Info("Restarting connection", + zap.Error(err), + zap.Duration("backoff", timeout), + ) c.connMux.Lock() c.conn = c.createPrimaryConn(nil) diff --git a/telegram/internal/manager/conn.go b/telegram/internal/manager/conn.go index 0532d5df62..bc81705aa9 100644 --- a/telegram/internal/manager/conn.go +++ b/telegram/internal/manager/conn.go @@ -123,10 +123,12 @@ func (c *Conn) Run(ctx context.Context) (err error) { defer func() { if err != nil && ctx.Err() == nil { c.log.Debug("Connection dead", zap.Error(err)) + } else { + c.log.Debug("Connection closed") } }() return c.proto.Run(ctx, func(ctx context.Context) error { - // Signal death on init error. Otherwise connection shutdown + // Signal death on init error. Otherwise, connection shutdown // deadlocks in OnSession that occurs before init fails. err := c.init(ctx) if err != nil { diff --git a/telegram/options.go b/telegram/options.go index 9af4ee213e..6e868181c5 100644 --- a/telegram/options.go +++ b/telegram/options.go @@ -146,7 +146,9 @@ func defaultBackoff(c clock.Clock) func() backoff.BackOff { return func() backoff.BackOff { b := backoff.NewExponentialBackOff() b.Clock = c - b.MaxElapsedTime = 0 + b.MaxElapsedTime = time.Minute + b.InitialInterval = time.Millisecond * 100 + b.MaxInterval = time.Second return b } }