One minute
Golang Options
golang里面, 经常要使用到 option的配置, 有时候配置项太多, 以至于不能在函数参数列表中进行解决, 如果处理到一个函数列表参数很长的函数, 估计得抽风了.
常见的解决方案:
- Config对象, 将参数放到 Config对象中, 但是这样会很臃肿, 尤其是 是否设置和0值的区分度 会变得很模糊. 如果使用指针避免了 0值的问题,那么, 指针的对象 一般意味着 修改的传递性, 那么, 使用指针也会变的疑惑. 实例化传递的指针 在使用过程中变化了, 会产生什么影响? 调用者会很惶恐, 充满着不确定性.
参考的文章1、2中指出了使用Option 的方式进行简化, 通过变长参数的方式 提升了 可配置性、可维护性.
在grpc-go的实现中, option使用了新的方式, 提供了Option对象的配置形式. 比如 DialOptions 这里列出grpc serverOptions的使用方式:
type serverOptions struct {
creds credentials.TransportCredentials
codec baseCodec
cp Compressor
dc Decompressor
unaryInt UnaryServerInterceptor
streamInt StreamServerInterceptor
inTapHandle tap.ServerInHandle
statsHandler stats.Handler
maxConcurrentStreams uint32
maxReceiveMessageSize int
maxSendMessageSize int
unknownStreamDesc *StreamDesc
keepaliveParams keepalive.ServerParameters
keepalivePolicy keepalive.EnforcementPolicy
initialWindowSize int32
initialConnWindowSize int32
writeBufferSize int
readBufferSize int
connectionTimeout time.Duration
maxHeaderListSize *uint32
}
var defaultServerOptions = serverOptions{
maxReceiveMessageSize: defaultServerMaxReceiveMessageSize,
maxSendMessageSize: defaultServerMaxSendMessageSize,
connectionTimeout: 120 * time.Second,
writeBufferSize: defaultWriteBufSize,
readBufferSize: defaultReadBufSize,
}
type ServerOption interface {
apply(*serverOptions)
}
func NewServer(opt ...ServerOption) *Server {
opts := defaultServerOptions
for _, o := range opt {
o.apply(&opts)
}
s := &Server{
lis: make(map[net.Listener]bool),
opts: opts,
conns: make(map[io.Closer]bool),
m: make(map[string]*service),
quit: make(chan struct{}),
done: make(chan struct{}),
czData: new(channelzData),
}
s.cv = sync.NewCond(&s.mu)
if EnableTracing {
_, file, line, _ := runtime.Caller(1)
s.events = trace.NewEventLog("grpc.Server", fmt.Sprintf("%s:%d", file, line))
}
if channelz.IsOn() {
s.channelzID = channelz.RegisterServer(&channelzServer{s}, "")
}
return s
}
参考
191 Words
2019-06-24 22:49 +0800