package constants import "time" // PollingShardCount 轮询队列默认分片数 // 千万级规模下,16 分片可将单队列深度控制在 ~60 万以内 const PollingShardCount = 16 // PollingBackpressureThreshold 单分片队列背压阈值 // 超过此深度时,Scheduler 跳过该分片本轮出队,防止 Asynq 积压过载 // 默认 50 万,可根据 Asynq Worker 处理速度调整 const PollingBackpressureThreshold = 500_000 // PollingDequeueMaxBatchSize Lua 脚本单次出队上限 // 受 Lua unpack() 的 LUAI_MAXCSTACK 约 8000 限制,保守取 7000 const PollingDequeueMaxBatchSize = 7000 // PollingDefaultMaxConcurrency 并发信号量默认上限 // 读取 Redis 配置 key 失败时使用,作为安全兜底值 // 300:支撑 10M 卡、2小时 carddata 间隔(Gateway 200ms → 300并发 = 1500任务/秒/类型) const PollingDefaultMaxConcurrency = 300 // PollingDefaultTotalMaxConcurrency 全部轮询任务共享的默认总并发上限。 const PollingDefaultTotalMaxConcurrency = 100 // PollingMaxConcurrencyLimit 轮询并发配置的代码安全上限。 const PollingMaxConcurrencyLimit = 1000 // PollingConcurrencyKeyTTL 并发计数 key 的过期时间(秒) // 保证 Worker 意外崩溃(defer Decr 未执行)时计数器在此时间内自动归零 const PollingConcurrencyKeyTTL = 600 // 10 分钟 // 轮询手动触发日志状态常量 const ( // PollingManualTriggerStatusPending 轮询手动触发日志状态-待处理 PollingManualTriggerStatusPending = "pending" // PollingManualTriggerStatusProcessing 轮询手动触发日志状态-处理中 PollingManualTriggerStatusProcessing = "processing" // PollingManualTriggerStatusCompleted 轮询手动触发日志状态-已完成 PollingManualTriggerStatusCompleted = "completed" // PollingManualTriggerStatusCancelled 轮询手动触发日志状态-已取消 PollingManualTriggerStatusCancelled = "cancelled" ) // PollingPriorityMaxAttempts 优先轮询项固定的最大尝试次数。 // 尝试次数只在真正发起执行后累加;达到上限记录失败终态并出队。 // 本值不是可维护配置项,也不改变普通轮询的无限重试策略。 const PollingPriorityMaxAttempts = 3 // PollingPriorityValidity 优先轮询项固定的有效期长度。 // 自入队时间(事实行 priority_effective_from)起算,超期仍未完成的项转已过期终态并出队, // 保留触发类型、尝试次数与最近失败原因。与尝试上限同为代码常量,不新增可维护配置项。 // 取 72 小时:覆盖最长轮询间隔叠加三次可恢复重试的时间,避免正常加急被过早判为超期。 const PollingPriorityValidity = 72 * time.Hour // TaskTypePollingPriorityExpiry 优先轮询项有效期到期处理任务类型(由 Asynq Scheduler 调度)。 // 该任务只扫描并终结超期未完成项,MUST NOT 依赖查询或读侧隐式触发; // 未在 QueueForTaskType 中单独声明,按该函数默认分支落在 default 队列。 const TaskTypePollingPriorityExpiry = "polling_priority:expiry" // PollingPriorityClaimLease 优先轮询项的认领租约(秒)。 // 必须长于既有轮询任务超时 60 秒,为执行收尾与重新入队留出余量; // 执行中且超过租约仍未被更新的优先项允许相邻执行接管领取。 const PollingPriorityClaimLease = 90 // 轮询优先队列状态常量 const ( // PollingPriorityStatusPending 优先轮询项状态-待执行(活动项) PollingPriorityStatusPending = "pending" // PollingPriorityStatusProcessing 优先轮询项状态-执行中(活动项,受认领租约保护) PollingPriorityStatusProcessing = "processing" // PollingPriorityStatusCompleted 优先轮询项状态-已完成(终态,已出队) PollingPriorityStatusCompleted = "completed" // PollingPriorityStatusFailed 优先轮询项状态-失败出队(终态) PollingPriorityStatusFailed = "failed" // PollingPriorityStatusClosed 优先轮询项状态-已关闭(人工关闭终态,已出队) PollingPriorityStatusClosed = "closed" // PollingPriorityStatusExpired 优先轮询项状态-已过期(有效期到期终态,已出队) PollingPriorityStatusExpired = "expired" ) // PollingPriorityActiveStatuses 返回占用活动项唯一键的状态集合。 // 与事实表部分唯一索引谓词 status IN ('pending','processing') 严格一致: // 已关闭与已过期是终态,不占键位,同一卡同一任务类型可再次入队或人工重触发。 func PollingPriorityActiveStatuses() []string { return []string{PollingPriorityStatusPending, PollingPriorityStatusProcessing} } // 轮询优先项执行结局常量(资产详情投影口径)。 // 与项状态区分:项状态描述队列位置(含待执行、失败出队),结局描述「最近一次轮询的对外结论」。 const ( // PollingPriorityOutcomeProcessing 结局-处理中(待执行或执行中) PollingPriorityOutcomeProcessing = "processing" // PollingPriorityOutcomeSuccess 结局-执行成功 PollingPriorityOutcomeSuccess = "success" // PollingPriorityOutcomeFailed 结局-轮询失败 PollingPriorityOutcomeFailed = "failed" // PollingPriorityOutcomeClosed 结局-已关闭 PollingPriorityOutcomeClosed = "closed" // PollingPriorityOutcomeExpired 结局-已过期 PollingPriorityOutcomeExpired = "expired" ) // 轮询优先项触发类型常量 const ( // PollingPriorityTriggerPurchaseActivated 主套餐购买后立即生效 PollingPriorityTriggerPurchaseActivated = "purchase_activated" // PollingPriorityTriggerRenewalActivated 同载体在本次生效前已存在更早套餐使用记录 PollingPriorityTriggerRenewalActivated = "renewal_activated" // PollingPriorityTriggerQueueActivated 排队主套餐顺延生效 PollingPriorityTriggerQueueActivated = "queue_activated" // PollingPriorityTriggerAddonActivated 加油包生效 PollingPriorityTriggerAddonActivated = "addon_activated" // PollingPriorityTriggerNoValidPackage 资产无有效套餐且存在待生效套餐使用记录 PollingPriorityTriggerNoValidPackage = "no_valid_package" // PollingPriorityTriggerManual 具备既有人工触发权限的账号人工入队 PollingPriorityTriggerManual = "manual_trigger" ) // PollingPriorityManualReasonMaxLength 是人工优先入队原因的长度上限,与事实表 manual_reason 列一致。 const PollingPriorityManualReasonMaxLength = 500 // 轮询优先项执行结果常量 const ( // PollingPriorityResultSuccess 优先轮询项执行成功 PollingPriorityResultSuccess = "success" // PollingPriorityResultFailed 优先轮询项执行失败 PollingPriorityResultFailed = "failed" ) // 轮询优先项请求可靠事件常量 const ( // OutboxEventTypePollingPriorityRequested 表示业务成功事实请求为该资源的卡建立优先轮询项。 // 载荷中的卡快照在业务事务内冻结,消费者据此逐卡建项并下发执行提示。 OutboxEventTypePollingPriorityRequested = "polling.priority.requested" // PollingPriorityRequestedPayloadVersionV1 是优先轮询请求事件载荷版本。 PollingPriorityRequestedPayloadVersionV1 = 1 // PollingPriorityEventKeyPrefix 是优先轮询请求事件的 event_id 命名空间前缀。 // 必须与既有 card-observation: 前缀分离:公共 Outbox 的 event_id 是全局幂等键, // 复用既有前缀会被 OnConflict DoNothing 静默去重,导致加急永不生效且无任何报错。 // // 长度预算:Outbox 的 event_id 列为 varchar(64),前缀与后缀共同保证生成的 ID 明显低于上限 // (当前最长形式为 prio:nvp:{载体检字}:{载体ID}:{秒级时间戳},不超过 43 字符)。 // 前缀与后缀都不得再加长;新增场景必须按同一预算核算。 PollingPriorityEventKeyPrefix = "prio:" ) // PollingPriorityTaskTypes 返回纳入优先轮询的既有轮询任务类型。 // 一次优先需求对应这些任务类型各执行一次;保护期一致性检查不在集合内。 // 返回新切片,调用方修改不会影响其它调用方。 func PollingPriorityTaskTypes() []string { return []string{ TaskTypePollingRealname, TaskTypePollingCarddata, TaskTypePollingPackage, TaskTypePollingCardStatus, } } // PollingPriorityStatusName 返回优先轮询项状态的中文名称。 func PollingPriorityStatusName(status string) string { switch status { case PollingPriorityStatusPending: return "待执行" case PollingPriorityStatusProcessing: return "执行中" case PollingPriorityStatusCompleted: return "已完成" case PollingPriorityStatusFailed: return "失败出队" case PollingPriorityStatusClosed: return "已关闭" case PollingPriorityStatusExpired: return "已过期" default: return "未知" } } // PollingPriorityStatusOutcome 把优先项状态投影为对外执行结局。 // 待执行与执行中都属于「处理中」:二者都没有产生新的对外结论。 func PollingPriorityStatusOutcome(status string) string { switch status { case PollingPriorityStatusCompleted: return PollingPriorityOutcomeSuccess case PollingPriorityStatusFailed: return PollingPriorityOutcomeFailed case PollingPriorityStatusClosed: return PollingPriorityOutcomeClosed case PollingPriorityStatusExpired: return PollingPriorityOutcomeExpired default: return PollingPriorityOutcomeProcessing } } // PollingPriorityOutcomeName 返回优先项执行结局的中文名称。 func PollingPriorityOutcomeName(outcome string) string { switch outcome { case PollingPriorityOutcomeSuccess: return "执行成功" case PollingPriorityOutcomeFailed: return "轮询失败" case PollingPriorityOutcomeClosed: return "已关闭" case PollingPriorityOutcomeExpired: return "已过期" case PollingPriorityOutcomeProcessing: return "处理中" default: return "未知" } } // PollingPriorityActive 判断状态是否为占用活动项唯一键的状态。 func PollingPriorityActive(status string) bool { return status == PollingPriorityStatusPending || status == PollingPriorityStatusProcessing } // PollingPriorityRetriggerable 判断状态是否允许人工重触发。 // 只有失败出队与已过期的项才需要人工重新加急;已完成与已关闭是人工/系统已经确认的结论。 func PollingPriorityRetriggerable(status string) bool { return status == PollingPriorityStatusFailed || status == PollingPriorityStatusExpired } // PollingPriorityTriggerName 返回优先轮询项触发类型的中文名称。 func PollingPriorityTriggerName(triggerType string) string { switch triggerType { case PollingPriorityTriggerPurchaseActivated: return "主套餐购买后立即生效" case PollingPriorityTriggerRenewalActivated: return "续购套餐生效" case PollingPriorityTriggerQueueActivated: return "排队主套餐顺延生效" case PollingPriorityTriggerAddonActivated: return "加油包生效" case PollingPriorityTriggerNoValidPackage: return "资产无有效套餐" case PollingPriorityTriggerManual: return "人工入队" default: return "未知" } } // PollingPriorityResultName 返回优先轮询项执行结果的中文名称。 func PollingPriorityResultName(result string) string { switch result { case PollingPriorityResultSuccess: return "成功" case PollingPriorityResultFailed: return "失败" default: return "未出结果" } } // PollingPriorityTaskTypeName 返回优先轮询任务类型的中文名称。 func PollingPriorityTaskTypeName(taskType string) string { switch taskType { case TaskTypePollingRealname: return "实名检查" case TaskTypePollingCarddata: return "流量检查" case TaskTypePollingPackage: return "套餐检查" case TaskTypePollingCardStatus: return "卡状态检查" default: return "未知" } }