8.4 KiB
8.4 KiB
Context 超时控制改进工作总结
时间: 2026-06-10
任务: Week 3-4 - 为所有核心模块添加 Context 超时控制
🎯 目标
为所有 Repository 和 Service 层方法添加 context.Context 参数,实现:
- 数据库操作超时控制
- 请求取消传播
- 优雅的超时错误处理
- 提升系统稳定性和可控性
✅ 已完成工作
1. Wallet 模块(100% 完成)
Repository 层
- ✅
Account(ctx context.Context, userID uint64) (*AccountDTO, error) - ✅
Ledger(ctx context.Context, userID uint64, page, pageSize int) (*PaginatedResult, error) - ✅
Recharge(ctx context.Context, userID uint64, amountCent int64) (*AccountDTO, error) - ✅
ConfirmRechargeFromChannel(ctx context.Context, userID uint64, bizNo string, amountCent int64) error - ✅
Withdraw(ctx context.Context, userID uint64, amountCent int64) (*AccountDTO, error) - ✅
AdminLedger(ctx context.Context, query AdminLedgerQuery) (*PaginatedResult, error)
Service 层
- ✅ 所有方法签名已更新,添加
ctx context.Context作为第一个参数 - ✅ 所有对 Repository 的调用已传递 context
Handler 层
- ✅ 所有 handler 方法使用
c.Request.Context()获取请求上下文 - ✅ Context 从 HTTP 请求传递到 Service 再到 Repository
测试代码
- ✅ Service 测试已更新(5 个测试)
- ✅ Repository 集成测试已更新(9 个测试)
- ✅ Repository 逻辑测试已更新(14 个测试)
- ✅ 所有测试通过
数据库操作
- ✅ 所有数据库查询使用
db.WithContext(ctx) - ✅ 事务操作传播 context
🔄 待完成工作
2. Order 模块(待开始)
Repository 层方法(预估 ~20 个):
Create(ctx context.Context, userID uint64, req CreateRequest)Cancel(ctx context.Context, userID uint64, orderID uint64)Pay(ctx context.Context, orderID uint64)SubmitHandoff(ctx context.Context, userID uint64, orderID uint64, req SubmitHandoffRequest)ConfirmReceive(ctx context.Context, userID uint64, orderID uint64)SubmitReturn(ctx context.Context, userID uint64, orderID uint64, req SubmitReturnRequest)SubmitCheckout(ctx context.Context, userID uint64, orderID uint64, req SubmitCheckoutRequest)ConfirmCheckout(ctx context.Context, userID uint64, orderID uint64)CounterCheckout(ctx context.Context, userID uint64, orderID uint64, req CounterCheckoutRequest)AcceptCheckout(ctx context.Context, userID uint64, orderID uint64)- ... 更多方法
Service 层:所有对应方法
Handler 层:所有对应 handler
测试代码:28 个测试用例需要更新
3. Payment 模块(待开始)
Repository 层方法(预估 ~15 个):
Start(ctx context.Context, userID uint64, orderID uint64, req StartPaymentRequest, clientIP string)Query(ctx context.Context, paymentNo string)HandleNotify(ctx context.Context, provider string, data map[string]string)StartRefund(ctx context.Context, orderID uint64, amountCent int64, bizType, reason string)AdminQuery(ctx context.Context, query AdminPaymentQuery)- ... 更多方法
Service 层:所有对应方法
Handler 层:所有对应 handler
测试代码:41 个测试用例需要更新
4. Listing 模块(待开始)
Repository 层方法(预估 ~10 个):
Create(ctx context.Context, userID uint64, req CreateListingRequest)Update(ctx context.Context, userID uint64, listingID uint64, req UpdateListingRequest)Delete(ctx context.Context, userID uint64, listingID uint64)List(ctx context.Context, query ListingQuery)Detail(ctx context.Context, listingID uint64)- ... 更多方法
5. 其他模块
- Dispute 模块
- Realname 模块
- AdminUser 模块
- PaymentConfig 模块
📋 实施建议
方案 A:手动逐模块修改(推荐)
优点:
- 精确控制每个修改
- 可以同步优化代码结构
- 确保测试全部通过
缺点:
- 工作量大(预估 8-12 小时)
- 需要逐个测试验证
步骤:
- 按模块优先级排序:order → payment → listing → 其他
- 每个模块按层级修改:Repository → Service → Handler → Tests
- 每完成一个模块,运行测试验证
- 提交一次代码
方案 B:自动化脚本批量修改(快速但风险高)
优点:
- 快速完成(1-2 小时)
- 统一规范
缺点:
- 可能引入错误
- 需要大量测试验证
- 可能遗漏边界情况
不推荐原因:
- 各模块方法签名差异较大
- 有些方法可能已有 context 参数
- 测试代码结构复杂,难以批量处理
方案 C:分阶段实施(平衡方案)
第一阶段(本次):
- ✅ Wallet 模块(已完成)
第二阶段(下次):
- Order 模块(核心业务,优先级最高)
- Payment 模块(核心业务,优先级最高)
第三阶段(后续):
- Listing、Dispute、Realname 等模块
提交策略:
- 每完成一个模块,提交一次
- 保持每次提交的原子性和可回滚性
🎯 推荐方案
采用方案 C - 分阶段实施
本次工作范围
- ✅ Wallet 模块(已完成)
- 提交本次工作
- 更新改进计划文档
下次工作范围
- Order 模块 Context 改造
- Payment 模块 Context 改造
- 运行所有测试验证
- 提交代码
后续工作
- 其他模块 Context 改造
- 全局测试验证
- 性能测试(验证超时控制效果)
📊 预估工作量
| 模块 | Repository 方法数 | Service 方法数 | Handler 数 | 测试用例数 | 预估时间 |
|---|---|---|---|---|---|
| ✅ Wallet | 6 | 5 | 5 | 28 | 2h(已完成) |
| Order | ~20 | ~20 | ~15 | 28 | 4h |
| Payment | ~15 | ~15 | ~10 | 41 | 3h |
| Listing | ~10 | ~10 | ~8 | ~10 | 2h |
| 其他 | ~15 | ~15 | ~10 | ~20 | 2h |
| 总计 | ~66 | ~65 | ~48 | ~127 | 13h |
🔍 实施细节
Context 传递链路
HTTP Request
↓
Handler (c.Request.Context())
↓
Service (ctx context.Context, ...)
↓
Repository (ctx context.Context, ...)
↓
GORM (db.WithContext(ctx))
超时控制示例
// Handler 层设置超时
func (h *Handler) CreateOrder(c *gin.Context) {
ctx, cancel := context.WithTimeout(c.Request.Context(), 5*time.Second)
defer cancel()
order, err := h.service.Create(ctx, userID, req)
// ...
}
// Repository 层传播 context
func (r *Repository) Create(ctx context.Context, userID uint64, req CreateRequest) error {
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
// 事务内的所有操作都会使用 ctx 的超时控制
// ...
})
}
测试代码模式
func TestRepositoryMethod(t *testing.T) {
db := setupTestDB(t)
defer cleanupTestDB(t, db)
repo := NewRepository(db)
ctx := context.Background()
result, err := repo.Method(ctx, params)
// ...
}
✅ 验证清单
每个模块完成后需要验证:
- 所有 Repository 方法签名已更新
- 所有 Service 方法签名已更新
- 所有 Handler 方法已传递 context
- 所有数据库操作使用
WithContext(ctx) - 所有测试代码已更新
- 所有测试通过(
go test ./internal/modules/<module> -v) - 代码编译通过(
go build ./internal/modules/<module>) - 无 lint 错误(
golangci-lint run ./internal/modules/<module>)
📝 注意事项
- 向后兼容性:这是一个破坏性变更(breaking change),所有调用方都需要更新
- 超时时间设置:
- 简单查询:2-5s
- 复杂查询:5-10s
- 事务操作:10-30s
- 外部 API 调用:根据 SLA 设置
- 错误处理:需要区分超时错误和业务错误
- 测试覆盖:确保所有路径都覆盖到 context 取消场景
🚀 下一步行动
立即行动(本次会话)
- ✅ 提交 Wallet 模块 Context 改造
- ✅ 更新改进计划文档
- ✅ 创建本文档作为工作记录
后续行动(下次会话)
- 开始 Order 模块 Context 改造
- 完成 Payment 模块 Context 改造
- 运行所有测试验证
- 提交代码
当前状态: Wallet 模块已完成,准备提交
下一目标: Order 和 Payment 模块 Context 改造
预计完成时间: 剩余 11 小时工作量