Files
gitea-pages/pkg/middleware/config/config_etcd.go
2025-10-09 15:33:21 +08:00

98 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package config
import (
"context"
"crypto/tls"
"fmt"
"os"
"time"
clientv3 "go.etcd.io/etcd/client/v3"
"go.uber.org/zap"
)
// ConfigEtcd 实现了KVConfig接口的etcd配置存储
type ConfigEtcd struct {
client *clientv3.Client
lease clientv3.Lease
}
// NewConfigEtcd 创建一个新的etcd配置存储实例
// endpoints是etcd集群的地址列表如["localhost:2379"]
// tlsConfig是TLS配置如果为nil则使用无认证模式
func NewConfigEtcd(endpoints []string, tlsConfig *tls.Config) (*ConfigEtcd, error) {
if len(endpoints) == 0 {
return nil, fmt.Errorf("endpoints is empty")
}
zap.L().Debug("connect etcd", zap.Strings("endpoints", endpoints))
// 创建etcd客户端配置
cfg := clientv3.Config{
Endpoints: endpoints,
DialTimeout: 5 * time.Second,
TLS: tlsConfig,
}
// 建立连接
client, err := clientv3.New(cfg)
if err != nil {
return nil, fmt.Errorf("failed to create etcd client: %v", err)
}
// 创建lease用于处理TTL
lease := clientv3.NewLease(client)
return &ConfigEtcd{
client: client,
lease: lease,
}, nil
}
// Put 存储键值对,可以设置过期时间
func (e *ConfigEtcd) Put(ctx context.Context, key string, value string, ttl time.Duration) error {
if ttl == TtlKeep || ttl <= 0 {
// 无过期时间,直接存储
_, err := e.client.Put(ctx, key, value)
return err
}
// 创建lease
resp, err := e.lease.Grant(ctx, int64(ttl.Seconds()))
if err != nil {
return fmt.Errorf("failed to grant lease: %v", err)
}
// 关联lease存储键值对
_, err = e.client.Put(ctx, key, value, clientv3.WithLease(resp.ID))
return err
}
// Get 获取键对应的值
func (e *ConfigEtcd) Get(ctx context.Context, key string) (string, error) {
resp, err := e.client.Get(ctx, key)
if err != nil {
return "", fmt.Errorf("failed to get key: %v", err)
}
if len(resp.Kvs) == 0 {
return "", os.ErrNotExist
}
return string(resp.Kvs[0].Value), nil
}
// Delete 删除指定的键
func (e *ConfigEtcd) Delete(ctx context.Context, key string) error {
_, err := e.client.Delete(ctx, key)
return err
}
// Close 关闭etcd客户端连接
func (e *ConfigEtcd) Close() error {
if err := e.lease.Close(); err != nil {
zap.L().Warn("failed to close etcd lease", zap.Error(err))
}
return e.client.Close()
}