Browse Source

Merge pull request #7420 from heyitsanthony/dial-timeout-report

clientv3: pass back dial error on dial timeout
Anthony Romano 8 years ago
parent
commit
317f3571ff
2 changed files with 25 additions and 10 deletions
  1. 23 8
      clientv3/client.go
  2. 2 2
      clientv3/client_test.go

+ 23 - 8
clientv3/client.go

@@ -48,7 +48,9 @@ type Client struct {
 	Auth
 	Auth
 	Maintenance
 	Maintenance
 
 
-	conn             *grpc.ClientConn
+	conn     *grpc.ClientConn
+	dialerrc chan error
+
 	cfg              Config
 	cfg              Config
 	creds            *credentials.TransportCredentials
 	creds            *credentials.TransportCredentials
 	balancer         *simpleBalancer
 	balancer         *simpleBalancer
@@ -214,7 +216,14 @@ func (c *Client) dialSetupOpts(endpoint string, dopts ...grpc.DialOption) (opts
 		default:
 		default:
 		}
 		}
 		dialer := &net.Dialer{Timeout: t}
 		dialer := &net.Dialer{Timeout: t}
-		return dialer.DialContext(c.ctx, proto, host)
+		conn, err := dialer.DialContext(c.ctx, proto, host)
+		if err != nil {
+			select {
+			case c.dialerrc <- err:
+			default:
+			}
+		}
+		return conn, err
 	}
 	}
 	opts = append(opts, grpc.WithDialer(f))
 	opts = append(opts, grpc.WithDialer(f))
 
 
@@ -316,11 +325,12 @@ func newClient(cfg *Config) (*Client, error) {
 
 
 	ctx, cancel := context.WithCancel(baseCtx)
 	ctx, cancel := context.WithCancel(baseCtx)
 	client := &Client{
 	client := &Client{
-		conn:   nil,
-		cfg:    *cfg,
-		creds:  creds,
-		ctx:    ctx,
-		cancel: cancel,
+		conn:     nil,
+		dialerrc: make(chan error, 1),
+		cfg:      *cfg,
+		creds:    creds,
+		ctx:      ctx,
+		cancel:   cancel,
 	}
 	}
 	if cfg.Username != "" && cfg.Password != "" {
 	if cfg.Username != "" && cfg.Password != "" {
 		client.Username = cfg.Username
 		client.Username = cfg.Username
@@ -347,9 +357,14 @@ func newClient(cfg *Config) (*Client, error) {
 		case <-waitc:
 		case <-waitc:
 		}
 		}
 		if !hasConn {
 		if !hasConn {
+			err := grpc.ErrClientConnTimeout
+			select {
+			case err = <-client.dialerrc:
+			default:
+			}
 			client.cancel()
 			client.cancel()
 			conn.Close()
 			conn.Close()
-			return nil, grpc.ErrClientConnTimeout
+			return nil, err
 		}
 		}
 	}
 	}
 
 

+ 2 - 2
clientv3/client_test.go

@@ -72,9 +72,9 @@ func TestDialTimeout(t *testing.T) {
 
 
 	donec := make(chan error)
 	donec := make(chan error)
 	go func() {
 	go func() {
-		// without timeout, grpc keeps redialing if connection refused
+		// without timeout, dial continues forever on ipv4 blackhole
 		cfg := Config{
 		cfg := Config{
-			Endpoints:   []string{"localhost:12345"},
+			Endpoints:   []string{"http://254.0.0.1:12345"},
 			DialTimeout: 2 * time.Second}
 			DialTimeout: 2 * time.Second}
 		c, err := New(cfg)
 		c, err := New(cfg)
 		if c != nil || err == nil {
 		if c != nil || err == nil {