91 lines
2.2 KiB
Go
91 lines
2.2 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"log/slog"
|
|
"time"
|
|
|
|
"hyapp/pkg/logx"
|
|
)
|
|
|
|
func (a *App) startResourceEquipmentCleanupWorker(ctx context.Context) {
|
|
a.workers.Add(1)
|
|
go func() {
|
|
defer a.workers.Done()
|
|
ticker := time.NewTicker(a.resourceEquipmentCleanupWorkerCfg.PollInterval)
|
|
defer ticker.Stop()
|
|
for {
|
|
if err := a.runResourceEquipmentCleanupRound(ctx); err != nil && !errors.Is(err, context.Canceled) {
|
|
logx.Error(ctx, "wallet_resource_equipment_cleanup_round_failed", err)
|
|
}
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case <-ticker.C:
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
|
|
func (a *App) runResourceEquipmentCleanupRound(ctx context.Context) error {
|
|
if a.mysqlRepo == nil {
|
|
return nil
|
|
}
|
|
cfg := a.resourceEquipmentCleanupWorkerCfg
|
|
lockCtx, lockCancel := context.WithTimeout(ctx, cfg.QueryTimeout)
|
|
release, acquired, err := a.mysqlRepo.AcquireResourceEquipmentCleanupLock(lockCtx)
|
|
lockCancel()
|
|
if err != nil || !acquired {
|
|
return err
|
|
}
|
|
defer release()
|
|
|
|
totalScanned := 0
|
|
totalDeleted := 0
|
|
totalDeadlockRetries := 0
|
|
reachedEnd := false
|
|
for totalScanned < cfg.RoundMaxScannedRows {
|
|
pageCtx, pageCancel := context.WithTimeout(ctx, cfg.QueryTimeout)
|
|
result, pageErr := a.mysqlRepo.CleanupExpiredResourceEquipmentPage(
|
|
pageCtx,
|
|
cfg.ScanBatchSize,
|
|
cfg.DeleteBatchSize,
|
|
time.Now().UTC().UnixMilli(),
|
|
)
|
|
pageCancel()
|
|
if pageErr != nil {
|
|
return pageErr
|
|
}
|
|
totalScanned += result.ScannedCount
|
|
totalDeleted += result.DeletedCount
|
|
totalDeadlockRetries += result.DeadlockRetries
|
|
if result.ReachedEnd {
|
|
reachedEnd = true
|
|
break
|
|
}
|
|
if cfg.BatchPause > 0 {
|
|
timer := time.NewTimer(cfg.BatchPause)
|
|
select {
|
|
case <-ctx.Done():
|
|
if !timer.Stop() {
|
|
<-timer.C
|
|
}
|
|
return ctx.Err()
|
|
case <-timer.C:
|
|
}
|
|
}
|
|
}
|
|
|
|
if totalDeleted > 0 || totalDeadlockRetries > 0 {
|
|
// 日志只记录有实际回收或发生窄重试的轮次;空表巡检不制造周期性噪音。
|
|
logx.Info(ctx, "wallet_resource_equipment_cleanup_completed",
|
|
slog.Int("scanned_count", totalScanned),
|
|
slog.Int("deleted_count", totalDeleted),
|
|
slog.Int("deadlock_retries", totalDeadlockRetries),
|
|
slog.Bool("reached_end", reachedEnd),
|
|
)
|
|
}
|
|
return nil
|
|
}
|