From 3f4b22b013d869911b627e0f1e6730b904666852 Mon Sep 17 00:00:00 2001 From: hailin Date: Tue, 3 Mar 2026 21:58:52 -0800 Subject: [PATCH] docs(contribution): add detailed comments for backfill task and findAccountsWithIncompleteUnlock Explain the starvation root cause, unlock rules, pre-planting user scenario, and future scalability considerations (cursor-based pagination). Co-Authored-By: Claude Sonnet 4.6 --- .../schedulers/contribution.scheduler.ts | 16 ++++++++++++++-- .../contribution-account.repository.ts | 17 ++++++++++++++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/backend/services/contribution-service/src/application/schedulers/contribution.scheduler.ts b/backend/services/contribution-service/src/application/schedulers/contribution.scheduler.ts index 0d67b3ef..608f4210 100644 --- a/backend/services/contribution-service/src/application/schedulers/contribution.scheduler.ts +++ b/backend/services/contribution-service/src/application/schedulers/contribution.scheduler.ts @@ -283,8 +283,20 @@ export class ContributionScheduler implements OnModuleInit { } /** - * 每10分钟扫描并补发未完全解锁的贡献值 - * 处理因下级先于上级认种导致的层级/奖励档位未能及时分配的情况 + * 每10分钟扫描并补发未完全解锁的贡献值(全量处理,无数量上限) + * + * 处理场景: + * 1. 下级先于上级认种:下级认种时上级层级/奖励档位不足,贡献值暂存为 LEVEL_OVERFLOW, + * 待上级后续达到解锁条件后由本任务补发给上级。 + * 2. 预种用户(预先支付费用但稍后正式认种):其直推下级在 synced_adoptions 中的 + * status = MINING_ENABLED 后,本任务会检测到上级解锁条件满足并补发对应算力。 + * + * 解锁规则(见 ContributionCalculatorService): + * - 层级解锁:直推认种数 ≥ 1 → 5级,≥ 3 → 10级,≥ 5 → 15级(满解锁) + * - 奖励档位:hasAdopted → 1档,直推 ≥ 2 → 2档,直推 ≥ 4 → 3档(满解锁) + * + * 注意:全量处理(无 LIMIT)避免账户因排序靠后而被永久跳过(starvation 问题)。 + * Redis 锁 9 分钟,每 10 分钟触发一次,保证同一时间只有一个实例运行。 */ @Cron('*/10 * * * *') async processContributionBackfill(): Promise { diff --git a/backend/services/contribution-service/src/infrastructure/persistence/repositories/contribution-account.repository.ts b/backend/services/contribution-service/src/infrastructure/persistence/repositories/contribution-account.repository.ts index 127a6032..1c9666c6 100644 --- a/backend/services/contribution-service/src/infrastructure/persistence/repositories/contribution-account.repository.ts +++ b/backend/services/contribution-service/src/infrastructure/persistence/repositories/contribution-account.repository.ts @@ -239,10 +239,21 @@ export class ContributionAccountRepository implements IContributionAccountReposi * @param limit 返回的最大数量 * @returns 解锁状态不完整的账户列表 */ + /** + * 查找所有解锁状态不完整的账户,用于 processContributionBackfill 定时补发任务。 + * + * 满足以下任一条件的账户视为"不完整": + * - unlockedLevelDepth < 15:层级算力尚未解锁到第15级(需要直推认种用户数达到5个才能满解锁) + * - unlockedBonusTiers < 3:奖励档位尚未全部解锁(需要直推认种用户数达到4个才能满解锁) + * + * 注意事项: + * - 不设数量上限(无 LIMIT),确保每次定时任务都能处理全量账户,避免因账户排序靠后而永久跳过。 + * - 原因:此前限制 100 条 + 按 updatedAt ASC 排序,导致最近更新的账户(如预种用户)因排在第 + * 100 名之后,永远无法被处理(饥饿问题 / starvation)。 + * - 当账户量增长到数万级别时,可考虑改为游标分页(cursor-based pagination)逐批处理, + * 以控制单次 cron 任务的执行时长。当前规模(约 100-500 个账户)无性能压力。 + */ async findAccountsWithIncompleteUnlock(): Promise { - // 查找已认种但未达到满解锁状态的账户: - // - unlockedLevelDepth < 15 或 - // - unlockedBonusTiers < 3 const records = await this.client.contributionAccount.findMany({ where: { hasAdopted: true,