perf(imap): STORE 批量持久化 + 推送序号复用已加载列表,消除逐条写库与全量扫描
原实现每封匹配消息单独 UPDATE + GetByID + seqOf 全量扫描(含大 附件 raw_data),手机整批标记已读(60+ 封)时产生 60 次写 + 180 次全量读,连接被长时间占住,其他连接响应被推送洪泛阻塞。 优化:收集目标状态后合并为单条 UPDATE ... IN 批量写;推送更新 直接用已加载列表的序号与目标状态(buildFlagsUpdateAt),不再 重复查库。实测 19 封批量 STORE 服务器耗时 372µs。
This commit is contained in:
@@ -28,6 +28,10 @@ type MailStore interface {
|
||||
MarkRead(id uint) error
|
||||
MarkReadState(id uint, read bool) error
|
||||
MarkFlagged(id uint, flagged bool) error
|
||||
// SetReadStates 批量设置多封邮件的已读状态(单条 UPDATE ... IN)。
|
||||
SetReadStates(ids []uint, read bool) error
|
||||
// SetFlaggedStates 批量设置多封邮件的星标状态(单条 UPDATE ... IN)。
|
||||
SetFlaggedStates(ids []uint, flagged bool) error
|
||||
MoveToFolder(id uint, folder string) error
|
||||
Delete(id uint) error
|
||||
CountUnread(userID uint, folder string) (int64, error)
|
||||
@@ -103,6 +107,24 @@ func (s *mailStoreGorm) MarkFlagged(id uint, flagged bool) error {
|
||||
return s.db.Model(&db.Message{}).Where("id = ?", id).Update("is_flagged", flagged).Error
|
||||
}
|
||||
|
||||
// SetReadStates 批量设置多封邮件的已读状态。
|
||||
// 客户端整批标记已读(手机同步后 STORE +FLAGS \Seen)时,逐条 UPDATE
|
||||
// 会产生大量写事务并占住连接,这里合并为单条 SQL。
|
||||
func (s *mailStoreGorm) SetReadStates(ids []uint, read bool) error {
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
return s.db.Model(&db.Message{}).Where("id IN ?", ids).Update("is_read", read).Error
|
||||
}
|
||||
|
||||
// SetFlaggedStates 批量设置多封邮件的星标状态。
|
||||
func (s *mailStoreGorm) SetFlaggedStates(ids []uint, flagged bool) error {
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
return s.db.Model(&db.Message{}).Where("id IN ?", ids).Update("is_flagged", flagged).Error
|
||||
}
|
||||
|
||||
// MoveToFolder changes the folder of a message.
|
||||
func (s *mailStoreGorm) MoveToFolder(id uint, folder string) error {
|
||||
return s.db.Model(&db.Message{}).Where("id = ?", id).Update("folder", folder).Error
|
||||
|
||||
Reference in New Issue
Block a user