Files
junhong_cmp_fiber/.planning/phases/01-p0/01-02-SUMMARY.md

3.9 KiB
Raw Blame History

phase, plan, subsystem, tags, one_liner, dependency_graph, tech_stack, key_files, decisions, metrics, requirements
phase plan subsystem tags one_liner dependency_graph tech_stack key_files decisions metrics requirements
01-p0 02 task/polling
bug-fix
asynq
realname-activation
critical
修复 PollingHandler 缺失 asynq.Client 导致实名激活任务进入 RPush 降级而非 Asynq 队列的断链问题
requires provides affects
01-01 (CRITICAL-02 实名状态常量统一)
CRITICAL-03
PollingHandler 正确通过 Asynq 入队实名激活任务
internal/task/polling_handler.go
pkg/queue/handler.go
added patterns
依赖注入:通过构造函数参数传入 asynq.Client
asynq.Client.EnqueueContext 正式入队
modified
internal/task/polling_handler.go
pkg/queue/handler.go
删除 RPush 降级方案及 _ = task 废弃代码,直接使用 EnqueueContext 入队
asynqClient 参数位置redis 之后、gatewayClient 之前,与其他 Handler 构造函数风格一致
duration completed tasks files
3min 2026-03-27 1 2
CRITICAL-03

Phase 01 Plan 02: PollingHandler 注入 asynq.Client 修复实名激活断链 Summary

Objective

修复 CRITICAL-03triggerFirstRealnameActivation 因缺少 asynq.Client 注入,降级使用 Redis RPush 将任务写入无消费者的列表,导致首次实名后套餐激活任务永远不被消费。

What Was Built

修改文件

internal/task/polling_handler.go

  1. PollingHandler struct 新增 asynqClient *asynq.Client 字段
  2. NewPollingHandler 构造函数新增 asynqClient *asynq.Client 参数位置redis 之后gatewayClient 之前)
  3. triggerFirstRealnameActivation 改为 h.asynqClient.EnqueueContext(ctx, task),删除 RPush 降级代码和 _ = task

pkg/queue/handler.go

registerPollingHandlers 调用 task.NewPollingHandler 时补充 h.asynqClient 参数Handler struct 已有此字段,直接传入)

关键代码对比

修改前(降级代码):

// polling_handler.go
type PollingHandler struct {
    db            *gorm.DB
    redis         *redis.Client
    // asynqClient 缺失
    gatewayClient *gateway.Client
    ...
}

// triggerFirstRealnameActivation 内
task := asynq.NewTask(...)
activationKey := constants.RedisPollingManualQueueKey(constants.TaskTypePackageFirstActivation)
h.redis.RPush(ctx, activationKey, string(payloadBytes))  // 写入无消费者的列表
_ = task  // task 被丢弃

修改后(正确入队):

// polling_handler.go
type PollingHandler struct {
    db          *gorm.DB
    redis       *redis.Client
    asynqClient *asynq.Client  // 新增,用于提交 Asynq 任务
    gatewayClient *gateway.Client
    ...
}

// triggerFirstRealnameActivation 内
task := asynq.NewTask(...)
if _, err := h.asynqClient.EnqueueContext(ctx, task); err != nil {
    h.logger.Warn("提交首次实名激活任务失败", ...)
    continue
}

Verification Results

✅ go build ./... — 编译通过
✅ rg "_ = task" internal/task/polling_handler.go → PASS: _ = task 已删除
✅ rg "asynqClient.EnqueueContext" internal/task/polling_handler.go → PASS: EnqueueContext 已存在
✅ registerPollingHandlers 传入 h.asynqClient 参数

Commits

Task Commit Files
Task 1: PollingHandler 注入 asynqClientCRITICAL-03 20b4b6d internal/task/polling_handler.go, pkg/queue/handler.go

Deviations from Plan

None - 计划执行完全按规格书执行,无偏差。

CRITICAL-03 完成状态

CRITICAL-03 已修复

  • PollingHandler struct 含 asynqClient 字段
  • NewPollingHandler 接受 asynqClient 参数
  • triggerFirstRealnameActivation 使用 EnqueueContext不再 RPush
  • _ = task 已删除
  • pkg/queue/handler.go 传入 h.asynqClient
  • go build ./... 编译通过

Self-Check: PASSED

  • internal/task/polling_handler.go — FOUND
  • pkg/queue/handler.go — FOUND
  • Commit 20b4b6d — FOUND