feat(cache): implement database fallback for conversation sequence management
All checks were successful
Build Backend / build (push) Successful in 2m2s
Build Backend / build-docker (push) Successful in 1m23s

Improve the reliability of conversation sequence generation by implementing a fallback mechanism to the database when Redis is unavailable or when keys are missing.

- Add `GetNextSeq` to `MessageRepository` and implement it in `MessageRepositoryAdapter`.
- Update `ConversationCache` to fallback to DB in `GetConvMaxSeq`, `GetConvMaxSeqBatch`, and `GetNextSeq`.
- Ensure Redis TTL is refreshed after every `INCR` operation to prevent sequence counter expiration.
- Refactor service layers to handle sequence generation errors more explicitly.
- Add `IsEnabled` helper to `LayeredCache` for cleaner availability checks.
This commit is contained in:
2026-05-15 13:08:22 +08:00
parent 570b2d7afe
commit 6c14309624
6 changed files with 58 additions and 38 deletions

View File

@@ -474,13 +474,13 @@ func (s *groupService) broadcastMemberJoinNotice(groupID string, targetUserID st
if s.conversationCache != nil {
seq, seqErr := s.conversationCache.GetNextSeq(context.Background(), conv.ID)
if seqErr != nil {
zap.L().Warn("redis get next seq failed, falling back to DB",
zap.L().Warn("get next seq failed, skipping system message",
zap.String("convID", conv.ID),
zap.Error(seqErr),
)
} else {
msg.Seq = seq
return
}
msg.Seq = seq
}
if err := s.messageRepo.CreateMessageWithSeq(msg); err != nil {
zap.L().Warn("保存入群提示消息失败",
@@ -1399,13 +1399,13 @@ func (s *groupService) MuteMember(userID string, groupID string, targetUserID st
if s.conversationCache != nil {
seq, seqErr := s.conversationCache.GetNextSeq(context.Background(), conv.ID)
if seqErr != nil {
zap.L().Warn("redis get next seq failed, falling back to DB",
zap.L().Warn("get next seq failed, skipping system message",
zap.String("convID", conv.ID),
zap.Error(seqErr),
)
} else {
msg.Seq = seq
return nil
}
msg.Seq = seq
}
if err := s.messageRepo.CreateMessageWithSeq(msg); err != nil {