Skip to content

Commit

Permalink
Merge pull request #94 from RTradeLtd/rep-timeout
Browse files Browse the repository at this point in the history
make grpc dial timeouts configurable
  • Loading branch information
RT-nilPointer authored May 18, 2020
2 parents 4f4125b + c4cb92f commit 4d59b12
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 3 deletions.
21 changes: 18 additions & 3 deletions go/rep_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ import (
//Close is a function that closes a resource
type Close func() error

//NewReplicatorClientConstructor is a convenient way to make a NewReplicatorClient
//NewReplicatorClientConstructor is a convenient way to make a NewReplicatorClient.
//
//The underlying implementation of the returned ReplicatorClient may change in miner releases.
//To take better control of the ReplicatorClient, such as changing connection options,
//please construct it manually by copying the source code of this function, or implement the
//ReplicatorClient interface.
func NewReplicatorClientConstructor(myPrivateKey libcryto.PrivKey, server *AddrInfo, addPeer func(id peer.ID, ma multiaddr.Multiaddr), logger *zap.Logger) (ReplicatorClient, Close, error) {
p, err := NewSimpleConnectionProvider(myPrivateKey, addPeer, logger)
if err != nil {
Expand Down Expand Up @@ -54,6 +59,7 @@ type SimpleGRPCConnectionProvider struct {
tlsConfig *libp2ptls.Identity
opts []grpc.DialOption
addPeer func(id peer.ID, ma multiaddr.Multiaddr)
timeout time.Duration
l *zap.Logger
}

Expand Down Expand Up @@ -83,13 +89,22 @@ func NewSimpleConnectionProvider(pk libcryto.PrivKey, addPeer AddPeer, logger *z
grpc.WithDisableRetry(),
},
addPeer: addPeer,
timeout: time.Second, //default initial connection timeout
l: logger,
}, nil
}

//ErrConnectToSelf is returned by a connection provider if it attempts to connect to itself
var ErrConnectToSelf = errors.New("connection to self not allowed")

// SetInitConnectionTimeout sets the initial connection timeout when connecting to a server.
// A low time out allows skipping bad servers and addresses quickly.
// A long timeout prevents errors during high load situations.
// The default timeout is 1 second.
func (s *SimpleGRPCConnectionProvider) SetInitConnectionTimeout(d time.Duration) {
s.timeout = d
}

//ConnectionToServer returns grpc client connection from AddrInfo
func (s *SimpleGRPCConnectionProvider) ConnectionToServer(a *AddrInfo) (*grpc.ClientConn, error) {
id, err := a.GetID()
Expand Down Expand Up @@ -124,8 +139,8 @@ func (s *SimpleGRPCConnectionProvider) ConnectionToServer(a *AddrInfo) (*grpc.Cl
tlsConfig := s.tlsConfig.ReusableConfigForPeer(id)
opts := append(s.opts, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)))

//TODO: a better way to try multiple addresses
dialCtx, cancel := context.WithTimeout(context.Background(), time.Second)
// if we have multiple addresses, try them one by one with timeout.
dialCtx, cancel := context.WithTimeout(context.Background(), s.timeout)
defer cancel()

cc, err := grpc.DialContext(dialCtx, address, opts...)
Expand Down
14 changes: 14 additions & 0 deletions go/rep_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/tls"
"net"
"testing"
"time"

libp2ptls "github.com/RTradeLtd/go-libp2p-tls"
manet "github.com/multiformats/go-multiaddr-net"
Expand Down Expand Up @@ -59,3 +60,16 @@ func TestSimpleConnectionProvider(t *testing.T) {
t.Fatal("unimplemented error expected for err:", err)
}
}

func TestSimpleGRPCConnectionProvider_SetInitConnectionTimeout(t *testing.T) {
s, err := NewSimpleConnectionProvider(getMockHostKey(0).priv, nil, nil)
fatalOnError(t, err)
if s.timeout != time.Second {
t.Fatal("default timeout should be 1 second, got ", s.timeout)
}
newTimeout := 2 * time.Second
s.SetInitConnectionTimeout(newTimeout)
if s.timeout != newTimeout {
t.Fatalf(" timeout should be updated to %v, got %v", newTimeout, s.timeout)
}
}

0 comments on commit 4d59b12

Please sign in to comment.