github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/pkg/p2p/client_connector.go (about) 1 // Copyright 2021 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package p2p 15 16 import ( 17 "context" 18 "net" 19 "time" 20 21 "github.com/pingcap/errors" 22 "github.com/pingcap/log" 23 "github.com/pingcap/tiflow/pkg/security" 24 proto "github.com/pingcap/tiflow/proto/p2p" 25 "go.uber.org/zap" 26 "google.golang.org/grpc" 27 ) 28 29 type clientConnectOptions struct { 30 // network and addr are similar to the parameters 31 // to net.Dial. 32 network string 33 addr string 34 35 // credential is used to setup the connection to the gRPC server. 36 credential *security.Credential 37 // timeout specifies the DialTimeout of the connection. 38 timeout time.Duration 39 maxRecvMsgSize int 40 } 41 42 type cancelFn = func() 43 44 // clientConnector abstracts away the underlying gRPC operation of dialing and 45 // the creation of a gRPC client. 46 type clientConnector interface { 47 Connect(opts clientConnectOptions) (proto.CDCPeerToPeerClient, cancelFn, error) 48 } 49 50 type clientConnectorImpl struct{} 51 52 func newClientConnector() clientConnector { 53 return &clientConnectorImpl{} 54 } 55 56 // Connect creates a gRPC client connection to the server. 57 // the returned cancelFn must be called to close the connection. 58 func (c *clientConnectorImpl) Connect(opts clientConnectOptions) (proto.CDCPeerToPeerClient, cancelFn, error) { 59 securityOption, err := opts.credential.ToGRPCDialOption() 60 if err != nil { 61 return nil, nil, errors.Trace(err) 62 } 63 64 conn, err := grpc.Dial( 65 opts.addr, 66 securityOption, 67 grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(opts.maxRecvMsgSize)), 68 grpc.WithContextDialer(func(ctx context.Context, s string) (net.Conn, error) { 69 return net.DialTimeout(opts.network, s, opts.timeout) 70 }), 71 // We do not need a unary interceptor since we are not making any unary calls. 72 grpc.WithStreamInterceptor(grpcClientMetrics.StreamClientInterceptor())) 73 if err != nil { 74 log.Warn("gRPC dial error", zap.Error(err)) 75 return nil, nil, errors.Trace(err) 76 } 77 78 cancel := func() { 79 if err := conn.Close(); err != nil { 80 log.Warn("gRPC connection close error", zap.Error(err)) 81 } 82 } 83 84 return proto.NewCDCPeerToPeerClient(conn), cancel, nil 85 }