可靠性: 完善 R2 备份恢复与对象生命周期
This commit is contained in:
@@ -277,7 +277,8 @@ func SendMessage(ctx context.Context, cache cache.Cache) {
|
||||
}
|
||||
|
||||
// 上传图片(如有)
|
||||
var imageURL string
|
||||
var imageURL, imageKey string
|
||||
imageAttached := false
|
||||
if imageFile != nil {
|
||||
uploadedURL, err := storage.UploadPictureToS3(imageFile, imageHeader)
|
||||
if err != nil {
|
||||
@@ -291,6 +292,31 @@ func SendMessage(ctx context.Context, cache cache.Cache) {
|
||||
return
|
||||
}
|
||||
imageURL = uploadedURL
|
||||
defer func() {
|
||||
if imageAttached || imageKey != "" {
|
||||
return
|
||||
}
|
||||
if err := db.R2DeleteTasks.EnqueueValues(stdctx.Background(), conf.Upload.ImageBucket, []string{imageURL}); err != nil {
|
||||
logrus.WithError(err).Error("Failed to enqueue unresolved uploaded message image compensation")
|
||||
}
|
||||
}()
|
||||
parsedKey, owned, err := storage.ObjectKeyFromCDNURL(imageURL, conf.Upload.ImageBucketCDNHost)
|
||||
if err != nil || !owned || parsedKey == "" {
|
||||
logrus.WithError(err).WithField("owned", owned).Error("Failed to resolve uploaded message image key")
|
||||
ctx.SetInternalErrorFlash()
|
||||
ctx.Redirect(fmt.Sprintf("/_/%s/chat/%s", domain, token))
|
||||
return
|
||||
}
|
||||
imageKey = parsedKey
|
||||
// 只有消息图片元数据成功落库才标记 attached;此前任意失败出口都补偿新对象。
|
||||
defer func() {
|
||||
if imageAttached {
|
||||
return
|
||||
}
|
||||
if err := db.R2DeleteTasks.Enqueue(stdctx.Background(), conf.Upload.ImageBucket, []string{imageKey}); err != nil {
|
||||
logrus.WithError(err).WithField("key", imageKey).Error("Failed to enqueue uploaded message image compensation")
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// 内容安全检测(仅文本)
|
||||
@@ -341,11 +367,16 @@ func SendMessage(ctx context.Context, cache cache.Cache) {
|
||||
if _, err := db.MessageImages.Create(ctx.Request().Context(), db.CreateMessageImageOptions{
|
||||
MessageID: msg.ID,
|
||||
URL: imageURL,
|
||||
ObjectKey: imageKey,
|
||||
FileName: imageHeader.Filename,
|
||||
FileSize: imageHeader.Size,
|
||||
}); err != nil {
|
||||
logrus.WithError(err).Error("Failed to save message image")
|
||||
ctx.SetInternalErrorFlash()
|
||||
ctx.Redirect(fmt.Sprintf("/_/%s/chat/%s", domain, token))
|
||||
return
|
||||
}
|
||||
imageAttached = true
|
||||
}
|
||||
|
||||
// 达到上限时关闭对话(幂等,多实例同时执行也安全)
|
||||
|
||||
Reference in New Issue
Block a user