fix(imap): UIDVALIDITY 改为持久化随机值,修复数据库重建后客户端缓存永不失效
根因:Status() 硬编码 UidValidity=1。数据库重建后消息 ID 空间 完全变化(uid 2-166 对应完全不同的邮件),但 UIDVALIDITY 不变, Thunderbird 认为本地缓存(旧 uid 1-166)仍然有效,只下载"新增" (uid 167:*)与"缺失"(2,4,8,9)的少数邮件——列表只剩 1-3 封, 每次刷新数量随机。 修复(RFC 3501 UIDVALIDITY 语义):新增 mailbox_states 表, 每(用户,文件夹)首次访问随机生成并持久化 UIDVALIDITY;数据库 重建后新值触发客户端丢弃缓存全量重同步。0 值修正,不同用户/ 文件夹互相独立。 新增 TestMailboxStateUidValidity 单元测试。
This commit is contained in:
@@ -354,7 +354,6 @@ func (m *imapMailbox) Status(items []imap.StatusItem) (*imap.MailboxStatus, erro
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
status.Messages = uint32(len(messages))
|
||||
|
||||
var unseenCount uint32
|
||||
@@ -370,7 +369,16 @@ func (m *imapMailbox) Status(items []imap.StatusItem) (*imap.MailboxStatus, erro
|
||||
return nil, err
|
||||
}
|
||||
status.UidNext = uint32(maxID + 1)
|
||||
status.UidValidity = 1
|
||||
// UIDVALIDITY 持久化随机值(RFC 3501):数据库重建导致消息 ID 空间
|
||||
// 变化时该值随之改变,客户端才会丢弃旧缓存全量重同步。此前硬编码 1,
|
||||
// 数据库重建后 Thunderbird 等客户端缓存永不失效(只下载"新增"的
|
||||
// UID),表现为列表只剩少量邮件。
|
||||
uidValidity, err := m.stores.MailboxState.UidValidity(m.user.id, m.name)
|
||||
if err != nil {
|
||||
log.Printf("IMAP: 获取 UIDVALIDITY 失败 folder=%s: %v", m.name, err)
|
||||
uidValidity = 1
|
||||
}
|
||||
status.UidValidity = uidValidity
|
||||
|
||||
return status, nil
|
||||
}
|
||||
@@ -394,7 +402,6 @@ func (m *imapMailbox) ListMessages(uid bool, seqset *imap.SeqSet, items []imap.F
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(dbMessages) == 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -567,7 +574,6 @@ func (m *imapMailbox) SearchMessages(uid bool, criteria *imap.SearchCriteria) ([
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user