| 766 | } |
| 767 | |
| 768 | func (p *ConnPool) tryDial() { |
| 769 | for { |
| 770 | if p.closed() { |
| 771 | return |
| 772 | } |
| 773 | |
| 774 | // Probe dialing even when dialErrorsNum is saturated. Apply DialTimeout per probe |
| 775 | // attempt so custom dialers can't hang indefinitely. |
| 776 | ctx := context.Background() |
| 777 | var cancel context.CancelFunc |
| 778 | if p.cfg.DialTimeout > 0 { |
| 779 | ctx, cancel = context.WithTimeout(ctx, p.cfg.DialTimeout) |
| 780 | } |
| 781 | |
| 782 | conn, err := p.cfg.Dialer(ctx) |
| 783 | if cancel != nil { |
| 784 | cancel() |
| 785 | } |
| 786 | if err != nil { |
| 787 | p.setLastDialError(err) |
| 788 | time.Sleep(time.Second) |
| 789 | continue |
| 790 | } |
| 791 | |
| 792 | atomic.StoreUint32(&p.dialErrorsNum, 0) |
| 793 | _ = conn.Close() |
| 794 | return |
| 795 | } |
| 796 | } |
| 797 | |
| 798 | func (p *ConnPool) setLastDialError(err error) { |
| 799 | p.lastDialError.Store(&lastDialErrorWrap{err: err}) |