Add cache into typing status set queries

This commit is contained in:
LittleSheep 2024-08-23 21:58:40 +08:00
parent a8a3c8cc71
commit f97cb877f5

View File

@ -3,6 +3,7 @@ package services
import ( import (
"context" "context"
"fmt" "fmt"
"sync"
"git.solsynth.dev/hydrogen/dealer/pkg/hyper" "git.solsynth.dev/hydrogen/dealer/pkg/hyper"
"git.solsynth.dev/hydrogen/dealer/pkg/proto" "git.solsynth.dev/hydrogen/dealer/pkg/proto"
@ -11,13 +12,33 @@ import (
"git.solsynth.dev/hydrogen/messaging/pkg/internal/models" "git.solsynth.dev/hydrogen/messaging/pkg/internal/models"
) )
type statusQueryCacheEntry struct {
Account models.Account
Member models.ChannelMember
Channel models.Channel
}
var statusQueryCacheLock sync.Mutex
// Map for caching typing status queries [channel id][user id]
var statusQueryCache map[uint]map[uint]statusQueryCacheEntry
func SetTypingStatus(channelId uint, userId uint) error { func SetTypingStatus(channelId uint, userId uint) error {
var account models.Account var account models.Account
var member models.ChannelMember
var channel models.Channel
if channelLevel, ok := statusQueryCache[channelId]; ok {
if entry, ok := channelLevel[userId]; ok {
account = entry.Account
member = entry.Member
channel = entry.Channel
}
} else {
if err := database.C.Where("external_id = ?", userId).First(&account).Error; err != nil { if err := database.C.Where("external_id = ?", userId).First(&account).Error; err != nil {
return fmt.Errorf("account not found: %v", err) return fmt.Errorf("account not found: %v", err)
} }
var member models.ChannelMember
if err := database.C. if err := database.C.
Where("account_id = ? AND channel_id = ?", account.ID, channelId). Where("account_id = ? AND channel_id = ?", account.ID, channelId).
First(&member).Error; err != nil { First(&member).Error; err != nil {
@ -26,7 +47,6 @@ func SetTypingStatus(channelId uint, userId uint) error {
member.Account = account member.Account = account
} }
var channel models.Channel
if err := database.C. if err := database.C.
Preload("Members"). Preload("Members").
Where("id = ?", channelId). Where("id = ?", channelId).
@ -34,6 +54,15 @@ func SetTypingStatus(channelId uint, userId uint) error {
return fmt.Errorf("channel not found: %v", err) return fmt.Errorf("channel not found: %v", err)
} }
// Cache queries
statusQueryCacheLock.Lock()
if _, ok := statusQueryCache[channelId]; !ok {
statusQueryCache[channelId] = make(map[uint]statusQueryCacheEntry)
}
statusQueryCache[channelId][userId] = statusQueryCacheEntry{account, member, channel}
statusQueryCacheLock.Unlock()
}
var broadcastTarget []uint64 var broadcastTarget []uint64
for _, item := range channel.Members { for _, item := range channel.Members {
if item.AccountID == member.AccountID { if item.AccountID == member.AccountID {