Browse Source

clientv3: support unix endpoints

Anthony Romano 10 years ago
parent
commit
b74a42b286
3 changed files with 25 additions and 45 deletions
  1. 18 21
      clientv3/client.go
  2. 6 23
      integration/cluster.go
  3. 1 1
      tools/benchmark/cmd/util.go

+ 18 - 21
clientv3/client.go

@@ -15,6 +15,8 @@
 package clientv3
 
 import (
+	"net"
+	"net/url"
 	"sync"
 	"time"
 
@@ -65,12 +67,7 @@ func New(cfg Config) (*Client, error) {
 	if cfg.RetryDialer == nil {
 		cfg.RetryDialer = dialEndpointList
 	}
-	// use a temporary skeleton client to bootstrap first connection
-	conn, err := cfg.RetryDialer(&Client{cfg: cfg})
-	if err != nil {
-		return nil, err
-	}
-	return newClient(conn, &cfg)
+	return newClient(&cfg)
 }
 
 // NewFromURL creates a new etcdv3 client from a URL.
@@ -78,12 +75,6 @@ func NewFromURL(url string) (*Client, error) {
 	return New(Config{Endpoints: []string{url}})
 }
 
-// NewFromConn creates a new etcdv3 client from an established grpc Connection.
-func NewFromConn(conn *grpc.ClientConn) *Client { return mustNewClient(conn, nil) }
-
-// Clone creates a copy of client with the old connection and new API clients.
-func (c *Client) Clone() *Client { return mustNewClient(c.conn, &c.cfg) }
-
 // Close shuts down the client's etcd connections.
 func (c *Client) Close() error {
 	return c.conn.Close()
@@ -112,6 +103,15 @@ func (c *Client) Dial(endpoint string) (*grpc.ClientConn, error) {
 	} else {
 		opts = append(opts, grpc.WithInsecure())
 	}
+	if url, uerr := url.Parse(endpoint); uerr == nil && url.Scheme == "unix" {
+		f := func(a string, t time.Duration) (net.Conn, error) {
+			return net.DialTimeout("unix", a, t)
+		}
+		// strip unix:// prefix so certs work
+		endpoint = url.Host
+		opts = append(opts, grpc.WithDialer(f))
+	}
+
 	conn, err := grpc.Dial(endpoint, opts...)
 	if err != nil {
 		return nil, err
@@ -119,15 +119,7 @@ func (c *Client) Dial(endpoint string) (*grpc.ClientConn, error) {
 	return conn, nil
 }
 
-func mustNewClient(conn *grpc.ClientConn, cfg *Config) *Client {
-	c, err := newClient(conn, cfg)
-	if err != nil {
-		panic("expected no error")
-	}
-	return c
-}
-
-func newClient(conn *grpc.ClientConn, cfg *Config) (*Client, error) {
+func newClient(cfg *Config) (*Client, error) {
 	if cfg == nil {
 		cfg = &Config{RetryDialer: dialEndpointList}
 	}
@@ -140,6 +132,11 @@ func newClient(conn *grpc.ClientConn, cfg *Config) (*Client, error) {
 		c := credentials.NewTLS(tlscfg)
 		creds = &c
 	}
+	// use a temporary skeleton client to bootstrap first connection
+	conn, err := cfg.RetryDialer(&Client{cfg: *cfg, creds: creds})
+	if err != nil {
+		return nil, err
+	}
 	return &Client{
 		KV:      pb.NewKVClient(conn),
 		Lease:   pb.NewLeaseClient(conn),

+ 6 - 23
integration/cluster.go

@@ -31,7 +31,6 @@ import (
 
 	"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
 	"github.com/coreos/etcd/Godeps/_workspace/src/google.golang.org/grpc"
-	"github.com/coreos/etcd/Godeps/_workspace/src/google.golang.org/grpc/credentials"
 
 	"github.com/coreos/etcd/client"
 	"github.com/coreos/etcd/clientv3"
@@ -445,6 +444,7 @@ func (m *member) listenGRPC() error {
 	if err != nil {
 		return fmt.Errorf("listen failed on grpc socket %s (%v)", m.grpcAddr, err)
 	}
+	m.grpcAddr = "unix://" + m.grpcAddr
 	m.grpcListener = l
 	return nil
 }
@@ -454,29 +454,12 @@ func NewClientV3(m *member) (*clientv3.Client, error) {
 	if m.grpcAddr == "" {
 		return nil, fmt.Errorf("member not configured for grpc")
 	}
-	f := func(a string, t time.Duration) (net.Conn, error) {
-		return net.Dial("unix", a)
+	cfg := clientv3.Config{
+		Endpoints:   []string{m.grpcAddr},
+		DialTimeout: 5 * time.Second,
+		TLS:         m.ClientTLSInfo,
 	}
-	unixdialer := grpc.WithDialer(f)
-	opts := []grpc.DialOption{
-		unixdialer,
-		grpc.WithBlock(),
-		grpc.WithTimeout(5 * time.Second)}
-	if m.ClientTLSInfo != nil {
-		tlscfg, err := m.ClientTLSInfo.ClientConfig()
-		if err != nil {
-			return nil, err
-		}
-		creds := credentials.NewTLS(tlscfg)
-		opts = append(opts, grpc.WithTransportCredentials(creds))
-	} else {
-		opts = append(opts, grpc.WithInsecure())
-	}
-	conn, err := grpc.Dial(m.grpcAddr, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return clientv3.NewFromConn(conn), nil
+	return clientv3.New(cfg)
 }
 
 // Clone returns a member with the same server configuration. The returned

+ 1 - 1
tools/benchmark/cmd/util.go

@@ -58,7 +58,7 @@ func mustCreateClients(totalClients, totalConns uint) []*clientv3.Client {
 
 	clients := make([]*clientv3.Client, totalClients)
 	for i := range clients {
-		clients[i] = conns[i%int(totalConns)].Clone()
+		clients[i] = conns[i%int(totalConns)]
 	}
 	return clients
 }