feat(chat): implement sequence-based unread count tracking
Introduce a new mechanism for tracking read positions using message sequences (hasReadSeq), similar to OpenIM, to allow for O(1) unread count calculations. - Implement `UserReadSeq` caching in Redis with Lua scripts to prevent sequence regression (ensuring updates only occur if the new sequence is greater than the current one). - Update `ConversationCache` to support sequence-based unread count computation (`maxSeq - hasReadSeq`). - Refactor `MessageRepository` to use conditional updates for `last_read_seq` in the database. - Update `ChatService` to automatically update the sender's read sequence when sending a message. - Optimize `MarkAsRead` logic to update both database and Redis sequence caches and refine notification targets for private vs group chats. - Update `jpush` client to use pointer types for boolean fields to properly handle optional values in JSON.
This commit is contained in:
13
internal/cache/keys.go
vendored
13
internal/cache/keys.go
vendored
@@ -29,6 +29,9 @@ const (
|
||||
PrefixUnreadHash = "unread:hash"
|
||||
PrefixUnreadTotal = "unread:total"
|
||||
|
||||
// 已读位置相关(OpenIM 风格:缓存 hasReadSeq,用于 O(1) 未读数计算)
|
||||
PrefixUserReadSeq = "user_read_seq"
|
||||
|
||||
// 用户相关
|
||||
PrefixUserInfo = "users:info"
|
||||
PrefixUserMe = "users:me"
|
||||
@@ -244,3 +247,13 @@ func MessageIdempotentKey(senderID, clientMsgID string) string {
|
||||
func PushDedupKey(userID, messageID string) string {
|
||||
return fmt.Sprintf("push_dedup:%s:%s", userID, messageID)
|
||||
}
|
||||
|
||||
// UserReadSeqKey 用户已读位置缓存键(OpenIM 风格 SEQ_USER_READ:{convID}:{userID})
|
||||
func UserReadSeqKey(convID, userID string) string {
|
||||
return fmt.Sprintf("%s:%s:%s", PrefixUserReadSeq, convID, userID)
|
||||
}
|
||||
|
||||
// ConvMaxSeqKey 会话最大 seq 缓存键
|
||||
func ConvMaxSeqKey(convID string) string {
|
||||
return fmt.Sprintf("%s:%s", keyPrefixMsgSeq, convID)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user