reconnect-mym #1
108
etcd.go
Normal file
108
etcd.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package reconnect
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
)
|
||||
|
||||
// EtcdClient etcd客户端包装器
|
||||
type EtcdClient struct {
|
||||
config clientv3.Config
|
||||
client *clientv3.Client
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
// NewEtcdClient 创建新的etcd客户端
|
||||
func NewEtcdClient(config clientv3.Config) *EtcdClient {
|
||||
return &EtcdClient{
|
||||
config: config,
|
||||
}
|
||||
}
|
||||
|
||||
// Connect 建立etcd连接
|
||||
func (e *EtcdClient) Connect(ctx context.Context) error {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
|
||||
if e.client != nil {
|
||||
_ = e.client.Close()
|
||||
}
|
||||
|
||||
client, err := clientv3.New(e.config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("etcd new client failed: %w", err)
|
||||
}
|
||||
|
||||
// 测试连接
|
||||
timeoutCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
_, err = client.Status(timeoutCtx, e.config.Endpoints[0])
|
||||
if err != nil {
|
||||
_ = client.Close()
|
||||
return fmt.Errorf("etcd status check failed: %w", err)
|
||||
}
|
||||
|
||||
e.client = client
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close 关闭etcd连接
|
||||
func (e *EtcdClient) Close() error {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
|
||||
if e.client != nil {
|
||||
err := e.client.Close()
|
||||
e.client = nil
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Ping 检查etcd连接是否健康
|
||||
func (e *EtcdClient) Ping(ctx context.Context) error {
|
||||
e.mu.RLock()
|
||||
defer e.mu.RUnlock()
|
||||
|
||||
if e.client == nil {
|
||||
return fmt.Errorf("etcd client is nil")
|
||||
}
|
||||
|
||||
if len(e.config.Endpoints) == 0 {
|
||||
return fmt.Errorf("etcd endpoints is empty")
|
||||
}
|
||||
|
||||
timeoutCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
_, err := e.client.Status(timeoutCtx, e.config.Endpoints[0])
|
||||
return err
|
||||
}
|
||||
|
||||
// IsConnected 检查连接状态
|
||||
func (e *EtcdClient) IsConnected() bool {
|
||||
e.mu.RLock()
|
||||
defer e.mu.RUnlock()
|
||||
|
||||
return e.client != nil
|
||||
}
|
||||
|
||||
// GetClient 获取底层的etcd客户端
|
||||
func (e *EtcdClient) GetClient() *clientv3.Client {
|
||||
e.mu.RLock()
|
||||
defer e.mu.RUnlock()
|
||||
|
||||
return e.client
|
||||
}
|
||||
|
||||
// EtcdManager 创建etcd重连管理器
|
||||
func EtcdManager(config clientv3.Config, reconnectConfig *Config) *Manager {
|
||||
client := NewEtcdClient(config)
|
||||
return NewManager(client, reconnectConfig)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user