tidb 中关于 etcd go 开发的一点疑惑

139 天前
 YanSeven
type Client struct {
Cluster
KV
Lease
Watcher
Auth
Maintenance

conn *grpc.ClientConn

cfg Config
creds grpccredentials.TransportCredentials
resolver *resolver.EtcdManualResolver
mu *sync.RWMutex

ctx context.Context
cancel context.CancelFunc

// Username is a user name for authentication.
Username string
// Password is a password for authentication.
Password string
authTokenBundle credentials.Bundle

callOpts []grpc.CallOption

lgMu *sync.RWMutex
lg *zap.Logger
}

func newClient(cfg *Config) (*Client, error) {
.....
client.Cluster = NewCluster(client)
client.KV = NewKV(client)
client.Lease = NewLease(client)
client.Watcher = NewWatcher(client)
client.Auth = NewAuth(client)
client.Maintenance = NewMaintenance(client)
....
}

// NewLease 创建一个新的 Lease 实例。
func NewLease(client *clientv3.Client, purpose string) *Lease {
// 返回一个 Lease 结构体的指针。
return &Lease{
// 设置选举目的。
Purpose: purpose,
// 传入 etcd 客户端。
client: client,
// 基于主客户端创建一个专门用于租约操作的客户端。
lease: clientv3.NewLease(client),
}
}


在这个代码中,我记得一个 client 在构建的时候,会调用 newClient()通过配置好的 cfg 创建一个 client 结构体对象。那么,内部的接口已经赋值了具体的 Lease 对象“client.Lease = NewLease(client)”.

这个 NewLease 的实现是 TiDB 中的代码,代码中大量使用这种类似“职责分离”的逻辑,就是明明已经有了一个 etcd 的 client 对象了,还要额外再创加一个专门的 lease 的客户端对象。

这种代码实践是一种生产中是一种类似“最佳实践”的做法吗。

这种专门再创建一个 lease ,我能想到的理由如下:
1. 职责分离,不同的功能客户端负责各自的操作
2. 传进来的 client 可能只是一个声明好的空结构体,内部没有进行赋值。

不知道有没有看过 tidb 的大佬解惑这种设计。
1150 次点击
所在节点    程序员
2 条回复
Reficul
139 天前
具体没读过 TIDB 的代码,但是可能有几个好处:
1. 不同 Client 可能配置不一样;
2. 不同 Client 可以隔离连接。因为 GRPC 下面是 http/2 ,有时候多路复用在同一个 tcp 连接容易可能会引起问题,比如大请求饿死或者引起小请求的延迟。
YanSeven
139 天前
@Reficul 有道理,我感觉第二个比较合理,感谢。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/1137990

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX