2021-03-12 12:33:32 +00:00
|
|
|
package client
|
|
|
|
|
|
|
|
import (
|
2021-05-20 15:51:28 +00:00
|
|
|
"crypto/tls"
|
2021-03-12 12:33:32 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"google.golang.org/grpc"
|
|
|
|
)
|
|
|
|
|
2021-05-27 12:21:58 +00:00
|
|
|
const (
|
|
|
|
grpcScheme = "grpc"
|
|
|
|
grpcTLSScheme = "grpcs"
|
|
|
|
)
|
|
|
|
|
2021-03-12 12:33:32 +00:00
|
|
|
// Option is a Client's option.
|
|
|
|
type Option func(*cfg)
|
|
|
|
|
|
|
|
type cfg struct {
|
|
|
|
addr string
|
|
|
|
|
|
|
|
dialTimeout time.Duration
|
2021-12-24 10:18:57 +00:00
|
|
|
rwTimeout time.Duration
|
2021-03-12 12:33:32 +00:00
|
|
|
|
2021-05-20 15:51:28 +00:00
|
|
|
tlsCfg *tls.Config
|
|
|
|
|
2021-03-12 12:33:32 +00:00
|
|
|
conn *grpc.ClientConn
|
|
|
|
}
|
|
|
|
|
2021-12-24 10:18:57 +00:00
|
|
|
const (
|
|
|
|
defaultDialTimeout = 5 * time.Second
|
|
|
|
defaultRWTimeout = 1 * time.Minute
|
|
|
|
)
|
2021-03-12 12:33:32 +00:00
|
|
|
|
|
|
|
func defaultCfg() *cfg {
|
|
|
|
return &cfg{
|
|
|
|
dialTimeout: defaultDialTimeout,
|
2021-12-24 10:18:57 +00:00
|
|
|
rwTimeout: defaultRWTimeout,
|
2021-03-12 12:33:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// WithNetworkAddress returns option to specify
|
|
|
|
// network address of the remote server.
|
|
|
|
//
|
|
|
|
// Ignored if WithGRPCConn is provided.
|
|
|
|
func WithNetworkAddress(v string) Option {
|
|
|
|
return func(c *cfg) {
|
|
|
|
if v != "" {
|
|
|
|
c.addr = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-27 12:21:58 +00:00
|
|
|
// WithNetworkURIAddress combines WithNetworkAddress and WithTLSCfg options
|
|
|
|
// based on arguments.
|
|
|
|
//
|
|
|
|
// Do not use along with WithNetworkAddress and WithTLSCfg.
|
|
|
|
//
|
|
|
|
// Ignored if WithGRPCConn is provided.
|
|
|
|
func WithNetworkURIAddress(addr string, tlsCfg *tls.Config) []Option {
|
2022-03-09 09:56:02 +00:00
|
|
|
host, isTLS, err := ParseURI(addr)
|
2021-05-27 12:21:58 +00:00
|
|
|
if err != nil {
|
2022-03-09 09:56:02 +00:00
|
|
|
return nil
|
2021-05-27 12:21:58 +00:00
|
|
|
}
|
|
|
|
|
2022-03-09 09:56:02 +00:00
|
|
|
opts := make([]Option, 2)
|
|
|
|
opts[0] = WithNetworkAddress(host)
|
|
|
|
if isTLS {
|
2021-05-27 12:21:58 +00:00
|
|
|
if tlsCfg == nil {
|
|
|
|
tlsCfg = &tls.Config{}
|
|
|
|
}
|
2022-03-09 09:56:02 +00:00
|
|
|
opts[1] = WithTLSCfg(tlsCfg)
|
|
|
|
} else {
|
|
|
|
opts[1] = WithTLSCfg(nil)
|
2021-05-27 12:21:58 +00:00
|
|
|
}
|
|
|
|
|
2022-03-09 09:56:02 +00:00
|
|
|
return opts
|
2021-05-27 12:21:58 +00:00
|
|
|
}
|
|
|
|
|
2021-03-12 12:33:32 +00:00
|
|
|
// WithDialTimeout returns option to specify
|
|
|
|
// dial timeout of the remote server connection.
|
|
|
|
//
|
|
|
|
// Ignored if WithGRPCConn is provided.
|
|
|
|
func WithDialTimeout(v time.Duration) Option {
|
|
|
|
return func(c *cfg) {
|
|
|
|
if v > 0 {
|
|
|
|
c.dialTimeout = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-24 10:18:57 +00:00
|
|
|
// WithRWTimeout returns option to specify timeout
|
|
|
|
// for reading and writing single gRPC message.
|
|
|
|
func WithRWTimeout(v time.Duration) Option {
|
|
|
|
return func(c *cfg) {
|
|
|
|
if v > 0 {
|
|
|
|
c.rwTimeout = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-20 15:51:28 +00:00
|
|
|
// WithTLSCfg returns option to specify
|
|
|
|
// TLS configuration.
|
|
|
|
//
|
|
|
|
// Ignored if WithGRPCConn is provided.
|
|
|
|
func WithTLSCfg(v *tls.Config) Option {
|
|
|
|
return func(c *cfg) {
|
2021-05-27 12:21:58 +00:00
|
|
|
c.tlsCfg = v
|
2021-05-20 15:51:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-12 12:33:32 +00:00
|
|
|
// WithGRPCConn returns option to specify
|
|
|
|
// gRPC virtual connection.
|
|
|
|
func WithGRPCConn(v *grpc.ClientConn) Option {
|
|
|
|
return func(c *cfg) {
|
|
|
|
if v != nil {
|
|
|
|
c.conn = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|