fix(share): 单题卡缓存 key 补 user.Domain;纠正过期的 TTL 注释
先查了「缓存 key 漏项」到底有没有实际影响,结论是**当前没有**: - 用户域名只在注册时写入(register.go / CreateUser),没有改域名的入口, 所以两张卡的二维码内容不会在运行期变化 - ExternalURL / ShareBackground 来自配置,改了必须重启,而缓存是进程内的, 重启即清空 —— 不存在「配置变了缓存还在」的窗口 - 头像、背景上传走 R2 随机 key(picture/日期/随机 hex,内容不可变), 换图必然换 URL,key 随之变化,不会出现「同名不同图」 只有一条理论缺口:域名要是将来能被修改,单题卡 key 没算 user.Domain, 会出现最长一小时的「二维码指向旧域名」。补上这一项成本为零,先按事实算进去。 shareCardCacheKey 本来就含 Domain,两张卡现在一致。 顺带把两处「TTL 30 分钟」的注释改成 1 小时(代码一直是 time.Hour)。 新增 TestShareCardCacheKeysCoverDrawnFields:逐个改动画进图里的字段, 断言 key 必须随之变化;去掉 user.Domain 后立刻报 "user.Domain is drawn on the question card but not in questionShareCardCacheKey"。
This commit is contained in:
@@ -328,7 +328,7 @@ func (c *ttlCache) cleanup() {
|
||||
// 社交图标 URL 固定不变,基本永远命中;头像/背景变更时最多延迟 1 小时生效。
|
||||
var imageCache = newTTLCache(24)
|
||||
|
||||
// 分享图结果缓存,TTL 30 分钟。key 含用户资料指纹,资料变更后自动失效。
|
||||
// 分享图结果缓存,TTL 1 小时。key 含用户资料指纹,资料变更后自动失效。
|
||||
// 存的是 PNG 编码字节(约 0.2~1MB/张),限制 32 条,总内存 ≤ 32MB。
|
||||
var shareCardCache = newTTLCache(32)
|
||||
|
||||
@@ -561,7 +561,9 @@ func writeShareCardResponse(ctx context.Context, data []byte) {
|
||||
}
|
||||
|
||||
// shareCardCacheKey 基于用户资料生成缓存指纹。
|
||||
// 资料(名称/简介/头像/背景/社交链接)任何一项变更都会导致 key 变化,缓存自动失效。
|
||||
// 资料(域名/名称/简介/头像/背景/社交链接)任何一项变更都会导致 key 变化,缓存自动失效。
|
||||
// conf 里的 ExternalURL / ShareBackground 不入 key:改配置必须重启,进程内缓存随之清空。
|
||||
// 头像、背景走 R2 随机 key(内容不可变),换图即换 URL,也不会出现同名不同图。
|
||||
func shareCardCacheKey(user *db.User) string {
|
||||
h := md5.New()
|
||||
fmt.Fprintf(h, "%s|%s|%s|%s|%s|%s|%s|%s|%s|%s",
|
||||
@@ -948,7 +950,7 @@ func drawQuestionQRCard(canvas *image.RGBA, user *db.User, question *db.Question
|
||||
return nil
|
||||
}
|
||||
|
||||
// 单题分享图结果缓存,TTL 30 分钟,上限 16 条(1C1G 内存友好)。
|
||||
// 单题分享图结果缓存,TTL 1 小时,上限 16 条(1C1G 内存友好)。
|
||||
var questionShareCache = newTTLCache(16)
|
||||
|
||||
// QuestionShareCard 生成单个问题(问题+回答)的分享卡片图。
|
||||
@@ -1111,9 +1113,12 @@ func QuestionShareCard(ctx context.Context) {
|
||||
}
|
||||
|
||||
// questionShareCardCacheKey 基于问题内容与用户资料生成缓存指纹,内容/资料变更自动失效。
|
||||
// user.Domain 虽然当前不可改(只在注册时写入),但它进了二维码内容:一旦将来开放改域名,
|
||||
// 漏掉它就会出现「卡片二维码指向旧域名」的一小时窗口,这里先按事实把它算进去。
|
||||
func questionShareCardCacheKey(user *db.User, question *db.Question) string {
|
||||
h := md5.New()
|
||||
fmt.Fprintf(h, "q|%d|%s|%s|%s|%s|%s", question.ID, question.Content, question.Answer, user.Name, user.Avatar, user.Background)
|
||||
fmt.Fprintf(h, "q|%d|%s|%s|%s|%s|%s|%s",
|
||||
question.ID, question.Content, question.Answer, user.Domain, user.Name, user.Avatar, user.Background)
|
||||
return fmt.Sprintf("qshare:%x", h.Sum(nil))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user