From a2c44a8b65e16cd7bab91f40e801c148e6239716 Mon Sep 17 00:00:00 2001 From: Anthony Romano Date: Wed, 25 Jan 2017 09:32:39 -0800 Subject: [PATCH 1/2] clientv3: test closing client cancels blocking dials --- clientv3/client_test.go | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/clientv3/client_test.go b/clientv3/client_test.go index 1133375ebb9..2b2b6d593ae 100644 --- a/clientv3/client_test.go +++ b/clientv3/client_test.go @@ -16,6 +16,7 @@ package clientv3 import ( "fmt" + "net" "testing" "time" @@ -25,6 +26,47 @@ import ( "google.golang.org/grpc" ) +func TestDialCancel(t *testing.T) { + defer testutil.AfterTest(t) + + // accept first connection so client is created with dial timeout + ln, err := net.Listen("unix", "dialcancel:12345") + if err != nil { + t.Fatal(err) + } + defer ln.Close() + + ep := "unix://dialcancel:12345" + cfg := Config{ + Endpoints: []string{ep}, + DialTimeout: 30 * time.Second} + c, err := New(cfg) + if err != nil { + t.Fatal(err) + } + + // connect to ipv4 blackhole so dial blocks + c.SetEndpoints("http://254.0.0.1:12345") + + // issue Get to force redial attempts + go c.Get(context.TODO(), "abc") + + // wait a little bit so client close is after dial starts + time.Sleep(100 * time.Millisecond) + + donec := make(chan struct{}) + go func() { + defer close(donec) + c.Close() + }() + + select { + case <-time.After(5 * time.Second): + t.Fatalf("failed to close") + case <-donec: + } +} + func TestDialTimeout(t *testing.T) { defer testutil.AfterTest(t) From 56286ccd2924896fe8a7766dd7a5f8441ca3ab31 Mon Sep 17 00:00:00 2001 From: Anthony Romano Date: Tue, 24 Jan 2017 12:25:55 -0800 Subject: [PATCH 2/2] clientv3: use DialContext Fixes #7216 --- clientv3/client.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clientv3/client.go b/clientv3/client.go index 45e93c2c22e..368323f73f0 100644 --- a/clientv3/client.go +++ b/clientv3/client.go @@ -221,7 +221,8 @@ func (c *Client) dialSetupOpts(endpoint string, dopts ...grpc.DialOption) (opts return nil, c.ctx.Err() default: } - return net.DialTimeout(proto, host, t) + dialer := &net.Dialer{Timeout: t} + return dialer.DialContext(c.ctx, proto, host) } opts = append(opts, grpc.WithDialer(f))