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

132 lines
3.9 KiB
Markdown
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.
---
phase: 01-p0
plan: 02
subsystem: task/polling
tags: [bug-fix, asynq, realname-activation, critical]
one_liner: "修复 PollingHandler 缺失 asynq.Client 导致实名激活任务进入 RPush 降级而非 Asynq 队列的断链问题"
dependency_graph:
requires:
- 01-01 (CRITICAL-02 实名状态常量统一)
provides:
- CRITICAL-03: PollingHandler 正确通过 Asynq 入队实名激活任务
affects:
- internal/task/polling_handler.go
- pkg/queue/handler.go
tech_stack:
added: []
patterns:
- "依赖注入:通过构造函数参数传入 asynq.Client"
- "asynq.Client.EnqueueContext 正式入队"
key_files:
modified:
- internal/task/polling_handler.go
- pkg/queue/handler.go
decisions:
- "删除 RPush 降级方案及 _ = task 废弃代码,直接使用 EnqueueContext 入队"
- "asynqClient 参数位置redis 之后、gatewayClient 之前,与其他 Handler 构造函数风格一致"
metrics:
duration: "3min"
completed: "2026-03-27"
tasks: 1
files: 2
requirements:
- CRITICAL-03
---
# Phase 01 Plan 02: PollingHandler 注入 asynq.Client 修复实名激活断链 Summary
## Objective
修复 CRITICAL-03`triggerFirstRealnameActivation` 因缺少 `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 已有此字段,直接传入)
### 关键代码对比
**修改前(降级代码):**
```go
// 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 被丢弃
```
**修改后(正确入队):**
```go
// 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 ✅