This commit is contained in:
Cold
2026-01-16 13:42:15 +08:00
committed by 张斌
parent 1fe3f127c3
commit 138b81640c
3 changed files with 67 additions and 31 deletions

View File

@@ -2,6 +2,7 @@ package redis
import (
"context"
"errors"
"strings"
"sync"
"time"
@@ -14,27 +15,60 @@ import (
)
var (
// redisClient 内部使用的 Redis 客户端(单例模式)
redisClient *gredis.Redis
redisOnce sync.Once
)
// RedisClient 获取Redis客户端支持重试3次每次间隔2秒
func RedisClient() *gredis.Redis {
// getClient 获取 Redis 客户端(延迟初始化
func getClient() *gredis.Redis {
redisOnce.Do(func() {
for i := 0; i < 3; i++ {
redisClient = g.Redis()
if redisClient != nil {
ctx := context.Background()
if _, err := redisClient.Do(ctx, "PING"); err == nil {
return
}
}
time.Sleep(2 * time.Second)
}
redisClient = g.Redis()
})
return redisClient
}
// GetRedisClient 获取 Redis 客户端(供外部使用)
func GetRedisClient() *gredis.Redis {
return getClient()
}
// RedisClient 导出的 Redis 客户端(供 mongo.go 使用,兼容旧代码)
var RedisClient = getClient()
// Lock 分布式锁
func Lock(ctx context.Context, key string, expireSeconds int64, fn func(ctx context.Context) error) (success bool, err error) {
limit := 3
LOOP:
if limit < 0 {
return false, errors.New("锁重试次数耗尽")
}
limit--
if val, err := RedisClient.Set(ctx, key, true, gredis.SetOption{
TTLOption: gredis.TTLOption{
EX: &expireSeconds,
},
NX: true,
}); err != nil {
return false, err
} else {
if val.Bool() {
defer func(RedisClient *gredis.Redis, ctx context.Context, key string) {
if _, err = RedisClient.Del(ctx, key); err != nil {
glog.Errorf(ctx, "RedisClient.Del error: %v", err)
}
}(RedisClient, ctx, key)
if err = fn(ctx); err != nil {
return false, err
}
return true, nil
} else {
time.Sleep(time.Second)
goto LOOP
}
}
}
func GetReadStream(ctx context.Context, msg ...QueueMessage) error {
for _, t := range msg {
err := GetReadFromStream(ctx, t.StreamKey, t.GroupName, t.ConsumerName, t.BatchSize, t.BlockMs, t.AutoAck, t.HandleFunc)
@@ -164,9 +198,6 @@ func ReadFromStream(ctx context.Context, streamKey, groupName, consumerName stri
RECONNECT:
// 先尝试读取pending消息ID=0处理积压
glog.Debugf(ctx, "[DEBUG Redis] XREADGROUP GROUP %s %s COUNT %d BLOCK 0 STREAMS %s 0",
groupName, consumerName, count, streamKey)
result, err := redisClient.Do(execCtx,
"XREADGROUP", "GROUP", groupName, consumerName,
"COUNT", count,
@@ -179,9 +210,6 @@ RECONNECT:
// 如果没有pending消息读取新消息
if result == nil || result.IsEmpty() {
glog.Debugf(ctx, "[DEBUG Redis] 无pending消息读取新消息 XREADGROUP GROUP %s %s COUNT %d BLOCK %d STREAMS %s >",
groupName, consumerName, count, blockMs, streamKey)
result, err = redisClient.Do(execCtx,
"XREADGROUP", "GROUP", groupName, consumerName,
"COUNT", count,
@@ -193,8 +221,6 @@ RECONNECT:
}
}
glog.Debugf(ctx, "[DEBUG Redis] XREADGROUP 返回: %+v", result)
// 预分配容量,避免动态扩容
messages := make([]StreamMessage, 0, int(count))

View File

@@ -116,3 +116,13 @@ func GetHistoryContextLimit() int64 {
ctx := context.Background()
return g.Cfg().MustGet(ctx, "history.contextLimit", 5).Int64() // 默认5轮对话
}
// DocSyncMessage 文档同步消息结构RAGFlow与MongoDB同步
type DocSyncMessage struct {
DocId string `json:"docId"` // MongoDB文档ID
RagflowDocId string `json:"ragflowDocId"` // RAGFlow文档ID
TenantId string `json:"tenantId"` // 租户ID
DocType string `json:"docType"` // 文档类型speechcraft/product
Action string `json:"action"` // 操作类型sync_ragflow_id
Timestamp int64 `json:"timestamp"` // 时间戳
}