// retryConnection establishes a new connection func (c *Client) retryConnection(oldConn *grpc.ClientConn, err error) (*grpc.ClientConn, error) { c.mu.Lock() defer c.mu.Unlock() if err != nil { c.errors = append(c.errors, err) } if c.cancel == nil { return nil, c.ctx.Err() } if oldConn != c.conn { // conn has already been updated return c.conn, nil } oldConn.Close() if st, _ := oldConn.State(); st != grpc.Shutdown { // wait for shutdown so grpc doesn't leak sleeping goroutines oldConn.WaitForStateChange(c.ctx, st) } conn, dialErr := c.cfg.RetryDialer(c) if dialErr != nil { c.errors = append(c.errors, dialErr) return nil, dialErr } c.conn = conn return c.conn, nil }