71 lines
2.4 KiB
Go
71 lines
2.4 KiB
Go
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
|
||
}
|