2026-05-09 21:47:33 +08:00

71 lines
2.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package user
import (
"context"
"log/slog"
"strings"
"time"
"hyapp/pkg/logx"
userdomain "hyapp/services/user-service/internal/domain/user"
)
const (
defaultRegionRebuildLockTTL = 30 * time.Second
defaultRegionRebuildBatchSize = 500
)
// RegionRebuildWorkerOptions 控制 cron-service 触发的单批 user_region_rebuild_tasks 处理边界。
type RegionRebuildWorkerOptions struct {
// WorkerID 写入 task locked_by便于排查某个节点是否卡住任务。
WorkerID string
// LockTTL 是单个 task claim 后允许本节点持有的最长时间,过期可被其他节点接管。
LockTTL time.Duration
// BatchSize 是单次最多更新的 users 数量,避免大国家全量更新长事务。
BatchSize int
}
func normalizeRegionRebuildWorkerOptions(options RegionRebuildWorkerOptions) RegionRebuildWorkerOptions {
options.WorkerID = strings.TrimSpace(options.WorkerID)
if options.WorkerID == "" {
options.WorkerID = "user-region-rebuild"
}
if options.LockTTL <= 0 {
options.LockTTL = defaultRegionRebuildLockTTL
}
if options.BatchSize <= 0 {
options.BatchSize = defaultRegionRebuildBatchSize
}
return options
}
// ProcessNextRegionRebuildTask 处理一个待重算任务错误只影响本批cron-service 下一轮继续触发。
func (s *Service) ProcessNextRegionRebuildTask(ctx context.Context, options RegionRebuildWorkerOptions) (userdomain.RegionRebuildProcessResult, error) {
options = normalizeRegionRebuildWorkerOptions(options)
if s.regionRebuildRepository == nil {
return userdomain.RegionRebuildProcessResult{NoTask: true}, nil
}
result, err := s.regionRebuildRepository.ProcessNextRegionRebuildTask(ctx, options.WorkerID, s.now().UnixMilli(), options.LockTTL, options.BatchSize)
if err != nil {
logx.Error(ctx, "worker_batch_failed", err, slog.String("worker", "user_region_rebuild"), slog.String("worker_id", options.WorkerID), slog.Int("batch_size", options.BatchSize))
return result, err
}
if result.NoTask {
return result, nil
}
logx.Info(ctx, "worker_batch_processed",
slog.String("worker", "user_region_rebuild"),
slog.String("worker_id", options.WorkerID),
slog.Int64("task_id", result.TaskID),
slog.String("country", result.CountryCode),
slog.Int64("target_region_id", result.TargetRegionID),
slog.String("status", result.Status),
slog.Int("processed_users", result.ProcessedUsers),
slog.Int64("cursor_user_id", result.CursorUserID),
)
return result, nil
}