client: define dialOptions as interfaces instead of functions (#2230)

This commit is contained in:
Menghan Li 2018-07-19 17:33:42 -07:00 коммит произвёл GitHub
Родитель 4f4261e767
Коммит 445634bdcc
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 88 добавлений и 62 удалений

Просмотреть файл

@ -140,7 +140,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
cc.ctx, cc.cancel = context.WithCancel(context.Background()) cc.ctx, cc.cancel = context.WithCancel(context.Background())
for _, opt := range opts { for _, opt := range opts {
opt(&cc.dopts) opt.apply(&cc.dopts)
} }
if channelz.IsOn() { if channelz.IsOn() {

Просмотреть файл

@ -62,14 +62,40 @@ type dialOptions struct {
} }
// DialOption configures how we set up the connection. // DialOption configures how we set up the connection.
type DialOption func(*dialOptions) type DialOption interface {
apply(*dialOptions)
}
// EmptyDialOption does not alter the dial configuration. It can be embedded in
// another structure to build custom dial options.
//
// This API is EXPERIMENTAL.
type EmptyDialOption struct{}
func (EmptyDialOption) apply(*dialOptions) {}
// funcDialOption wraps a function that modifies dialOptions into an
// implementation of the DialOption interface.
type funcDialOption struct {
f func(*dialOptions)
}
func (fdo *funcDialOption) apply(do *dialOptions) {
fdo.f(do)
}
func newFuncDialOption(f func(*dialOptions)) *funcDialOption {
return &funcDialOption{
f: f,
}
}
// WithWaitForHandshake blocks until the initial settings frame is received from // WithWaitForHandshake blocks until the initial settings frame is received from
// the server before assigning RPCs to the connection. Experimental API. // the server before assigning RPCs to the connection. Experimental API.
func WithWaitForHandshake() DialOption { func WithWaitForHandshake() DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.waitForHandshake = true o.waitForHandshake = true
} })
} }
// WithWriteBufferSize determines how much data can be batched before doing a // WithWriteBufferSize determines how much data can be batched before doing a
@ -80,9 +106,9 @@ func WithWaitForHandshake() DialOption {
// Zero will disable the write buffer such that each write will be on underlying // Zero will disable the write buffer such that each write will be on underlying
// connection. Note: A Send call may not directly translate to a write. // connection. Note: A Send call may not directly translate to a write.
func WithWriteBufferSize(s int) DialOption { func WithWriteBufferSize(s int) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.copts.WriteBufferSize = s o.copts.WriteBufferSize = s
} })
} }
// WithReadBufferSize lets you set the size of read buffer, this determines how // WithReadBufferSize lets you set the size of read buffer, this determines how
@ -91,27 +117,27 @@ func WithWriteBufferSize(s int) DialOption {
// The default value for this buffer is 32KB. Zero will disable read buffer for // The default value for this buffer is 32KB. Zero will disable read buffer for
// a connection so data framer can access the underlying conn directly. // a connection so data framer can access the underlying conn directly.
func WithReadBufferSize(s int) DialOption { func WithReadBufferSize(s int) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.copts.ReadBufferSize = s o.copts.ReadBufferSize = s
} })
} }
// WithInitialWindowSize returns a DialOption which sets the value for initial // WithInitialWindowSize returns a DialOption which sets the value for initial
// window size on a stream. The lower bound for window size is 64K and any value // window size on a stream. The lower bound for window size is 64K and any value
// smaller than that will be ignored. // smaller than that will be ignored.
func WithInitialWindowSize(s int32) DialOption { func WithInitialWindowSize(s int32) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.copts.InitialWindowSize = s o.copts.InitialWindowSize = s
} })
} }
// WithInitialConnWindowSize returns a DialOption which sets the value for // WithInitialConnWindowSize returns a DialOption which sets the value for
// initial window size on a connection. The lower bound for window size is 64K // initial window size on a connection. The lower bound for window size is 64K
// and any value smaller than that will be ignored. // and any value smaller than that will be ignored.
func WithInitialConnWindowSize(s int32) DialOption { func WithInitialConnWindowSize(s int32) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.copts.InitialConnWindowSize = s o.copts.InitialConnWindowSize = s
} })
} }
// WithMaxMsgSize returns a DialOption which sets the maximum message size the // WithMaxMsgSize returns a DialOption which sets the maximum message size the
@ -125,9 +151,9 @@ func WithMaxMsgSize(s int) DialOption {
// WithDefaultCallOptions returns a DialOption which sets the default // WithDefaultCallOptions returns a DialOption which sets the default
// CallOptions for calls over the connection. // CallOptions for calls over the connection.
func WithDefaultCallOptions(cos ...CallOption) DialOption { func WithDefaultCallOptions(cos ...CallOption) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.callOptions = append(o.callOptions, cos...) o.callOptions = append(o.callOptions, cos...)
} })
} }
// WithCodec returns a DialOption which sets a codec for message marshaling and // WithCodec returns a DialOption which sets a codec for message marshaling and
@ -144,9 +170,9 @@ func WithCodec(c Codec) DialOption {
// //
// Deprecated: use UseCompressor instead. // Deprecated: use UseCompressor instead.
func WithCompressor(cp Compressor) DialOption { func WithCompressor(cp Compressor) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.cp = cp o.cp = cp
} })
} }
// WithDecompressor returns a DialOption which sets a Decompressor to use for // WithDecompressor returns a DialOption which sets a Decompressor to use for
@ -159,9 +185,9 @@ func WithCompressor(cp Compressor) DialOption {
// //
// Deprecated: use encoding.RegisterCompressor instead. // Deprecated: use encoding.RegisterCompressor instead.
func WithDecompressor(dc Decompressor) DialOption { func WithDecompressor(dc Decompressor) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.dc = dc o.dc = dc
} })
} }
// WithBalancer returns a DialOption which sets a load balancer with the v1 API. // WithBalancer returns a DialOption which sets a load balancer with the v1 API.
@ -170,11 +196,11 @@ func WithDecompressor(dc Decompressor) DialOption {
// Deprecated: use the new balancer APIs in balancer package and // Deprecated: use the new balancer APIs in balancer package and
// WithBalancerName. // WithBalancerName.
func WithBalancer(b Balancer) DialOption { func WithBalancer(b Balancer) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.balancerBuilder = &balancerWrapperBuilder{ o.balancerBuilder = &balancerWrapperBuilder{
b: b, b: b,
} }
} })
} }
// WithBalancerName sets the balancer that the ClientConn will be initialized // WithBalancerName sets the balancer that the ClientConn will be initialized
@ -190,16 +216,16 @@ func WithBalancerName(balancerName string) DialOption {
if builder == nil { if builder == nil {
panic(fmt.Sprintf("grpc.WithBalancerName: no balancer is registered for name %v", balancerName)) panic(fmt.Sprintf("grpc.WithBalancerName: no balancer is registered for name %v", balancerName))
} }
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.balancerBuilder = builder o.balancerBuilder = builder
} })
} }
// withResolverBuilder is only for grpclb. // withResolverBuilder is only for grpclb.
func withResolverBuilder(b resolver.Builder) DialOption { func withResolverBuilder(b resolver.Builder) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.resolverBuilder = b o.resolverBuilder = b
} })
} }
// WithServiceConfig returns a DialOption which has a channel to read the // WithServiceConfig returns a DialOption which has a channel to read the
@ -209,9 +235,9 @@ func withResolverBuilder(b resolver.Builder) DialOption {
// specified here. // specified here.
// https://github.com/grpc/grpc/blob/master/doc/service_config.md // https://github.com/grpc/grpc/blob/master/doc/service_config.md
func WithServiceConfig(c <-chan ServiceConfig) DialOption { func WithServiceConfig(c <-chan ServiceConfig) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.scChan = c o.scChan = c
} })
} }
// WithBackoffMaxDelay configures the dialer to use the provided maximum delay // WithBackoffMaxDelay configures the dialer to use the provided maximum delay
@ -236,43 +262,43 @@ func WithBackoffConfig(b BackoffConfig) DialOption {
// //
// This can be exported if arbitrary backoff strategies are allowed by gRPC. // This can be exported if arbitrary backoff strategies are allowed by gRPC.
func withBackoff(bs backoff.Strategy) DialOption { func withBackoff(bs backoff.Strategy) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.bs = bs o.bs = bs
} })
} }
// WithBlock returns a DialOption which makes caller of Dial blocks until the // WithBlock returns a DialOption which makes caller of Dial blocks until the
// underlying connection is up. Without this, Dial returns immediately and // underlying connection is up. Without this, Dial returns immediately and
// connecting the server happens in background. // connecting the server happens in background.
func WithBlock() DialOption { func WithBlock() DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.block = true o.block = true
} })
} }
// WithInsecure returns a DialOption which disables transport security for this // WithInsecure returns a DialOption which disables transport security for this
// ClientConn. Note that transport security is required unless WithInsecure is // ClientConn. Note that transport security is required unless WithInsecure is
// set. // set.
func WithInsecure() DialOption { func WithInsecure() DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.insecure = true o.insecure = true
} })
} }
// WithTransportCredentials returns a DialOption which configures a connection // WithTransportCredentials returns a DialOption which configures a connection
// level security credentials (e.g., TLS/SSL). // level security credentials (e.g., TLS/SSL).
func WithTransportCredentials(creds credentials.TransportCredentials) DialOption { func WithTransportCredentials(creds credentials.TransportCredentials) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.copts.TransportCredentials = creds o.copts.TransportCredentials = creds
} })
} }
// WithPerRPCCredentials returns a DialOption which sets credentials and places // WithPerRPCCredentials returns a DialOption which sets credentials and places
// auth state on each outbound RPC. // auth state on each outbound RPC.
func WithPerRPCCredentials(creds credentials.PerRPCCredentials) DialOption { func WithPerRPCCredentials(creds credentials.PerRPCCredentials) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.copts.PerRPCCredentials = append(o.copts.PerRPCCredentials, creds) o.copts.PerRPCCredentials = append(o.copts.PerRPCCredentials, creds)
} })
} }
// WithTimeout returns a DialOption that configures a timeout for dialing a // WithTimeout returns a DialOption that configures a timeout for dialing a
@ -280,15 +306,15 @@ func WithPerRPCCredentials(creds credentials.PerRPCCredentials) DialOption {
// //
// Deprecated: use DialContext and context.WithTimeout instead. // Deprecated: use DialContext and context.WithTimeout instead.
func WithTimeout(d time.Duration) DialOption { func WithTimeout(d time.Duration) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.timeout = d o.timeout = d
} })
} }
func withContextDialer(f func(context.Context, string) (net.Conn, error)) DialOption { func withContextDialer(f func(context.Context, string) (net.Conn, error)) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.copts.Dialer = f o.copts.Dialer = f
} })
} }
func init() { func init() {
@ -313,9 +339,9 @@ func WithDialer(f func(string, time.Duration) (net.Conn, error)) DialOption {
// WithStatsHandler returns a DialOption that specifies the stats handler for // WithStatsHandler returns a DialOption that specifies the stats handler for
// all the RPCs and underlying network connections in this ClientConn. // all the RPCs and underlying network connections in this ClientConn.
func WithStatsHandler(h stats.Handler) DialOption { func WithStatsHandler(h stats.Handler) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.copts.StatsHandler = h o.copts.StatsHandler = h
} })
} }
// FailOnNonTempDialError returns a DialOption that specifies if gRPC fails on // FailOnNonTempDialError returns a DialOption that specifies if gRPC fails on
@ -325,68 +351,68 @@ func WithStatsHandler(h stats.Handler) DialOption {
// //
// This is an EXPERIMENTAL API. // This is an EXPERIMENTAL API.
func FailOnNonTempDialError(f bool) DialOption { func FailOnNonTempDialError(f bool) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.copts.FailOnNonTempDialError = f o.copts.FailOnNonTempDialError = f
} })
} }
// WithUserAgent returns a DialOption that specifies a user agent string for all // WithUserAgent returns a DialOption that specifies a user agent string for all
// the RPCs. // the RPCs.
func WithUserAgent(s string) DialOption { func WithUserAgent(s string) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.copts.UserAgent = s o.copts.UserAgent = s
} })
} }
// WithKeepaliveParams returns a DialOption that specifies keepalive parameters // WithKeepaliveParams returns a DialOption that specifies keepalive parameters
// for the client transport. // for the client transport.
func WithKeepaliveParams(kp keepalive.ClientParameters) DialOption { func WithKeepaliveParams(kp keepalive.ClientParameters) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.copts.KeepaliveParams = kp o.copts.KeepaliveParams = kp
} })
} }
// WithUnaryInterceptor returns a DialOption that specifies the interceptor for // WithUnaryInterceptor returns a DialOption that specifies the interceptor for
// unary RPCs. // unary RPCs.
func WithUnaryInterceptor(f UnaryClientInterceptor) DialOption { func WithUnaryInterceptor(f UnaryClientInterceptor) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.unaryInt = f o.unaryInt = f
} })
} }
// WithStreamInterceptor returns a DialOption that specifies the interceptor for // WithStreamInterceptor returns a DialOption that specifies the interceptor for
// streaming RPCs. // streaming RPCs.
func WithStreamInterceptor(f StreamClientInterceptor) DialOption { func WithStreamInterceptor(f StreamClientInterceptor) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.streamInt = f o.streamInt = f
} })
} }
// WithAuthority returns a DialOption that specifies the value to be used as the // WithAuthority returns a DialOption that specifies the value to be used as the
// :authority pseudo-header. This value only works with WithInsecure and has no // :authority pseudo-header. This value only works with WithInsecure and has no
// effect if TransportCredentials are present. // effect if TransportCredentials are present.
func WithAuthority(a string) DialOption { func WithAuthority(a string) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.authority = a o.authority = a
} })
} }
// WithChannelzParentID returns a DialOption that specifies the channelz ID of // WithChannelzParentID returns a DialOption that specifies the channelz ID of
// current ClientConn's parent. This function is used in nested channel creation // current ClientConn's parent. This function is used in nested channel creation
// (e.g. grpclb dial). // (e.g. grpclb dial).
func WithChannelzParentID(id int64) DialOption { func WithChannelzParentID(id int64) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.channelzParentID = id o.channelzParentID = id
} })
} }
// WithDisableServiceConfig returns a DialOption that causes grpc to ignore any // WithDisableServiceConfig returns a DialOption that causes grpc to ignore any
// service config provided by the resolver and provides a hint to the resolver // service config provided by the resolver and provides a hint to the resolver
// to not fetch service configs. // to not fetch service configs.
func WithDisableServiceConfig() DialOption { func WithDisableServiceConfig() DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.disableServiceConfig = true o.disableServiceConfig = true
} })
} }
// WithDisableRetry returns a DialOption that disables retries, even if the // WithDisableRetry returns a DialOption that disables retries, even if the
@ -400,17 +426,17 @@ func WithDisableServiceConfig() DialOption {
// //
// This API is EXPERIMENTAL. // This API is EXPERIMENTAL.
func WithDisableRetry() DialOption { func WithDisableRetry() DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.disableRetry = true o.disableRetry = true
} })
} }
// WithMaxHeaderListSize returns a DialOption that specifies the maximum // WithMaxHeaderListSize returns a DialOption that specifies the maximum
// (uncompressed) size of header list that the client is prepared to accept. // (uncompressed) size of header list that the client is prepared to accept.
func WithMaxHeaderListSize(s uint32) DialOption { func WithMaxHeaderListSize(s uint32) DialOption {
return func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.copts.MaxHeaderListSize = &s o.copts.MaxHeaderListSize = &s
} })
} }
func defaultDialOptions() dialOptions { func defaultDialOptions() dialOptions {