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