Files
junhong_cmp_fiber/pkg/constants/polling.go
break 5ed6b39deb
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
feat(收口): 补齐 8 月迭代缺口并同步 Spec 与证据链
- 新增六对成对迁移 000232–000237:H5 弹窗类型、退款结算标识与申请人备注、优先轮询事实字段与两个新终态、通道阈值命中留痕、手机号最近解绑人、提现资格校验留痕
- 退款:原因必填与申请人备注、来源支付与渠道流水冻结、线下处理流水号补录审计、按订单查询可选退款方式、企微审批材料补齐且新增字段缺失映射即明确失败
- 优先轮询:人工关闭、有效期到期独立周期任务、失败与过期人工重触发、事实字段与异常重试查询、资产解析端点只读投影
- 通道阈值:命中事实同事务留痕与命中记录查询;员工账单:列表筛选与详情投影;商户池:列表投影与统计周期语义;H5:弹窗类型与类别排序
- 手机号:有效关联数量与最近解绑人、短信验证码失败次数限制;导出:佣金明细十五列与报表序号列
- 时间筛选:三处新增筛选纳入统一严格解析契约,员工账单产生时间参数改名
- 同步 12 份主 Spec 需求、两端点与异步任务证据链,门禁 context-health 与 OpenSpec 校验通过
2026-09-18 15:34:29 +08:00

273 lines
12 KiB
Go
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.
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 "未知"
}
}