feat(chat): implement sequence pre-allocation, versioned sync, and push worker
Introduce several performance and synchronization enhancements: - Implement `SeqBufferManager` to allow sequence number pre-allocation via Redis Lua scripts, reducing atomic increment overhead. - Add `PushWorker` to handle asynchronous message pushing using Redis Streams. - Implement incremental conversation synchronization via `ConversationVersionLog` to allow clients to fetch only recent changes. - Add support for Gzip compression in WebSocket communications to reduce bandwidth usage. - Update dependency injection and configuration to support these new components.
This commit is contained in:
@@ -18,6 +18,7 @@ import (
|
||||
"with_you/internal/repository"
|
||||
"with_you/internal/service"
|
||||
|
||||
redisPkg "github.com/redis/go-redis/v9"
|
||||
"github.com/google/wire"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
@@ -49,6 +50,12 @@ var InfrastructureSet = wire.NewSet(
|
||||
// WebSocket MessagePublisher
|
||||
ProvideWSMessagePublisher,
|
||||
|
||||
// Seq 预分配管理器
|
||||
ProvideSeqBufferManager,
|
||||
|
||||
// 推送 Worker
|
||||
ProvidePushWorker,
|
||||
|
||||
// 外部服务客户端
|
||||
ProvideOpenAIClient,
|
||||
ProvideTencentClient,
|
||||
@@ -275,3 +282,47 @@ func ProvideLogger() *zap.Logger {
|
||||
zap.ReplaceGlobals(logger)
|
||||
return logger
|
||||
}
|
||||
|
||||
// ProvideSeqBufferManager 提供 Seq 预分配管理器
|
||||
func ProvideSeqBufferManager(cfg *config.Config, redisClient *redis.Client, cacheBackend cache.Cache) *cache.SeqBufferManager {
|
||||
seqCfg := cache.SeqBufferConfig{
|
||||
Enabled: cfg.SeqBuffer.Enabled,
|
||||
PrivateBufferSize: cfg.SeqBuffer.PrivateBufferSize,
|
||||
GroupBufferSize: cfg.SeqBuffer.GroupBufferSize,
|
||||
LockTimeoutMs: cfg.SeqBuffer.LockTimeoutMs,
|
||||
MaxRetries: cfg.SeqBuffer.MaxRetries,
|
||||
}
|
||||
if !seqCfg.Enabled {
|
||||
return cache.NewSeqBufferManager(nil, seqCfg, nil, nil)
|
||||
}
|
||||
return cache.NewSeqBufferManagerFromRedisPkg(redisClient, seqCfg, nil, nil)
|
||||
}
|
||||
|
||||
// ProvidePushWorker 提供推送 Worker(Redis Stream 异步推送)
|
||||
func ProvidePushWorker(
|
||||
cfg *config.Config,
|
||||
redisClient *redis.Client,
|
||||
publisher ws.MessagePublisher,
|
||||
pushSvc service.PushService,
|
||||
msgRepo repository.MessageRepository,
|
||||
userRepo repository.UserRepository,
|
||||
) *service.PushWorker {
|
||||
pushCfg := service.PushWorkerConfig{
|
||||
Enabled: cfg.PushWorker.Enabled,
|
||||
Stream: cfg.PushWorker.Stream,
|
||||
Group: cfg.PushWorker.Group,
|
||||
BatchSize: cfg.PushWorker.BatchSize,
|
||||
PollTimeoutMs: cfg.PushWorker.PollTimeoutMs,
|
||||
MaxRetries: cfg.PushWorker.MaxRetries,
|
||||
MaxStreamLen: cfg.PushWorker.MaxStreamLen,
|
||||
IdleTimeoutMs: cfg.PushWorker.IdleTimeoutMs,
|
||||
}
|
||||
if !pushCfg.Enabled {
|
||||
return service.NewPushWorker(nil, nil, nil, nil, nil, pushCfg)
|
||||
}
|
||||
var rdb *redisPkg.Client
|
||||
if redisClient != nil {
|
||||
rdb = redisClient.GetClient()
|
||||
}
|
||||
return service.NewPushWorker(rdb, publisher, pushSvc, msgRepo, userRepo, pushCfg)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user