暂存一下,防止丢失
This commit is contained in:
72
internal/infrastructure/notification/cleanup.go
Normal file
72
internal/infrastructure/notification/cleanup.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package notification
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||||
)
|
||||
|
||||
// CleanupService 按通知类别的保留期限分批删除过期通知事实。
|
||||
type CleanupService struct {
|
||||
db *gorm.DB
|
||||
logger *zap.Logger
|
||||
now func() time.Time
|
||||
}
|
||||
|
||||
// NewCleanupService 创建通知保留清理服务。
|
||||
func NewCleanupService(db *gorm.DB, logger *zap.Logger) *CleanupService {
|
||||
if logger == nil {
|
||||
logger = zap.NewNop()
|
||||
}
|
||||
return &CleanupService{db: db, logger: logger, now: time.Now}
|
||||
}
|
||||
|
||||
// Run 按类别、创建时间和稳定主键执行有界分批清理。
|
||||
func (s *CleanupService) Run(ctx context.Context) error {
|
||||
policies := []struct {
|
||||
category string
|
||||
days int
|
||||
}{
|
||||
{constants.NotificationCategoryApproval, constants.NotificationApprovalRetentionDays},
|
||||
{constants.NotificationCategoryExpiry, constants.NotificationExpiryRetentionDays},
|
||||
{constants.NotificationCategorySync, constants.NotificationSyncRetentionDays},
|
||||
{constants.NotificationCategorySystem, constants.NotificationSystemRetentionDays},
|
||||
}
|
||||
for _, policy := range policies {
|
||||
deleted, err := s.cleanupCategory(ctx, policy.category, s.now().UTC().AddDate(0, 0, -policy.days))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.logger.Info("站内通知保留清理完成",
|
||||
zap.String("category", policy.category), zap.Int64("deleted_count", deleted))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *CleanupService) cleanupCategory(ctx context.Context, category string, cutoff time.Time) (int64, error) {
|
||||
var total int64
|
||||
for batch := 0; batch < constants.NotificationCleanupMaxBatches; batch++ {
|
||||
result := s.db.WithContext(ctx).Exec(`WITH candidates AS (
|
||||
SELECT id FROM tb_notification
|
||||
WHERE category = ? AND created_at < ?
|
||||
ORDER BY created_at ASC, id ASC
|
||||
LIMIT ?
|
||||
)
|
||||
DELETE FROM tb_notification AS notification
|
||||
USING candidates
|
||||
WHERE notification.id = candidates.id`, category, cutoff, constants.NotificationCleanupBatchSize)
|
||||
if result.Error != nil {
|
||||
return total, errors.Wrap(errors.CodeDatabaseError, result.Error, "清理站内通知失败")
|
||||
}
|
||||
total += result.RowsAffected
|
||||
if result.RowsAffected < constants.NotificationCleanupBatchSize {
|
||||
break
|
||||
}
|
||||
}
|
||||
return total, nil
|
||||
}
|
||||
Reference in New Issue
Block a user