⚡ Add cache into typing status set queries
This commit is contained in:
		| @@ -3,6 +3,7 @@ package services | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"sync" | ||||
|  | ||||
| 	"git.solsynth.dev/hydrogen/dealer/pkg/hyper" | ||||
| 	"git.solsynth.dev/hydrogen/dealer/pkg/proto" | ||||
| @@ -11,27 +12,55 @@ import ( | ||||
| 	"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 { | ||||
| 	var account models.Account | ||||
| 	if err := database.C.Where("external_id = ?", userId).First(&account).Error; err != nil { | ||||
| 		return fmt.Errorf("account not found: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	var member models.ChannelMember | ||||
| 	if err := database.C. | ||||
| 		Where("account_id = ? AND channel_id = ?", account.ID, channelId). | ||||
| 		First(&member).Error; err != nil { | ||||
| 		return fmt.Errorf("channel member not found: %v", err) | ||||
| 	} else { | ||||
| 		member.Account = account | ||||
| 	} | ||||
|  | ||||
| 	var channel models.Channel | ||||
| 	if err := database.C. | ||||
| 		Preload("Members"). | ||||
| 		Where("id = ?", channelId). | ||||
| 		First(&channel).Error; err != nil { | ||||
| 		return fmt.Errorf("channel not found: %v", err) | ||||
|  | ||||
| 	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 { | ||||
| 			return fmt.Errorf("account not found: %v", err) | ||||
| 		} | ||||
|  | ||||
| 		if err := database.C. | ||||
| 			Where("account_id = ? AND channel_id = ?", account.ID, channelId). | ||||
| 			First(&member).Error; err != nil { | ||||
| 			return fmt.Errorf("channel member not found: %v", err) | ||||
| 		} else { | ||||
| 			member.Account = account | ||||
| 		} | ||||
|  | ||||
| 		if err := database.C. | ||||
| 			Preload("Members"). | ||||
| 			Where("id = ?", channelId). | ||||
| 			First(&channel).Error; err != nil { | ||||
| 			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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user