This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-08-31
|
||||
13
openspec/changes/add-priority-polling-queue/design.md
Normal file
13
openspec/changes/add-priority-polling-queue/design.md
Normal file
@@ -0,0 +1,13 @@
|
||||
## Context
|
||||
|
||||
优先轮询是普通轮询之上的高优先级调度,不是另一套轮询业务逻辑。自动套餐事件、无有效套餐、普通轮询异常补偿和受控人工触发均可入队;优先与普通轮询共享同一卡互斥和既有并发边界。
|
||||
|
||||
## Decisions
|
||||
|
||||
- 队列表保存卡、活动状态、合并来源、触发类型、来源订单/套餐使用、尝试次数和结果;同一卡活动项唯一。
|
||||
- 在订单/套餐生效、无有效套餐识别、普通轮询异常后通过可靠事件入队;具备既有手动轮询权限的后台账号可在数据范围内通过 `POST /priority-polling-queue` 提交 `asset_identifier` 与必填 `reason`。消费者按来源事实幂等合并,不能由支付回调直接重复写队列。
|
||||
- Worker 用行锁领取优先项,复用普通轮询既有并发上限、外部调用保护、套餐/流量/状态同步和失败重试;普通轮询查询活动项排除对应卡。完成或最终失败出队并写触发来源、操作来源、次数、时间和结果审计。
|
||||
|
||||
## Migration Plan
|
||||
|
||||
新增成对迁移、活动项唯一索引和来源索引;隔离库验证三种自动触发、回调重放、同卡合并、普通互斥、失败重试和 up/down/up。
|
||||
24
openspec/changes/add-priority-polling-queue/proposal.md
Normal file
24
openspec/changes/add-priority-polling-queue/proposal.md
Normal file
@@ -0,0 +1,24 @@
|
||||
## Scope
|
||||
|
||||
- 迭代编号:`AUG26-016`。
|
||||
|
||||
## Why
|
||||
|
||||
紧急卡状态查询与普通轮询竞争,无法保证处理顺序或追踪加急事实。
|
||||
|
||||
## What Changes
|
||||
|
||||
- 新增受限管理的卡轮询优先队列。
|
||||
- Worker 优先领取队列项,并以唯一活动项和锁避免同卡并发。
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `priority-polling-queue`: 卡轮询加急队列。
|
||||
|
||||
### Modified Capabilities
|
||||
- 无。
|
||||
|
||||
## Impact
|
||||
|
||||
影响后台卡管理、异步轮询、运营商调用、审计和 Schema。
|
||||
@@ -0,0 +1,8 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 优先轮询队列
|
||||
系统 SHALL 在不改变普通轮询内容、并发上限和失败重试的前提下,为指定业务场景创建高优先级轮询任务。同一资产未完成优先任务必须合并触发来源、次数和最近时间,而不得重复执行同一轮轮询。
|
||||
|
||||
#### Scenario: 规则命中
|
||||
- **WHEN** 业务请求或任务满足本需求定义的前置条件
|
||||
- **THEN** 系统按上述规则完成处理、保留可追溯事实,并拒绝与状态、权限或幂等约束冲突的重复操作
|
||||
@@ -0,0 +1,21 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 套餐生命周期自动优先入队
|
||||
系统 SHALL 在下列业务事实提交成功后,将关联资产对应卡自动加入优先轮询队列:无有效套餐、新购套餐首次成为有效套餐、已过期套餐完成续购、流量用尽后购买的加油包完成生效,及普通轮询出现既有异常补偿条件。具备既有轮询手动触发权限的后台账号也可为其数据范围内资产手动入队并必须填写原因。入队必须等待订单、支付、套餐使用记录提交成功;失败或取消订单不得入队。队列项记录触发类型(新购、过期续购、加油包)、来源订单/套餐使用记录、触发时间及执行结果。
|
||||
|
||||
同一卡只能有一条活动优先项。多个触发同时到达时,系统合并来源事实、保留最近触发时间,且最多执行一次未完成优先轮询;不得因重复支付回调、任务重放或相同订单重试重复入队。手动入队不允许修改调度优先级或绕过既有并发上限;它与自动/异常触发合并到同一卡活动项。
|
||||
|
||||
#### Scenario: 人工与异常补偿触发合并
|
||||
- **WHEN** 同一卡已有自动入队活动项,管理员手动触发或普通轮询异常补偿再次触发
|
||||
- **THEN** 系统仅追加触发来源、次数和最近时间,不创建第二项或重复调用轮询
|
||||
|
||||
#### Scenario: 重复支付成功回调
|
||||
- **WHEN** 已生效套餐订单的支付成功回调重复投递
|
||||
- **THEN** 系统仅创建或更新一条关联该卡的活动优先队列项
|
||||
|
||||
### Requirement: 优先领取、执行与出队审计
|
||||
Worker SHALL 先领取活动优先项,再执行既有套餐、流量和卡状态轮询;普通轮询不得与已领取优先项并发。领取时使用行锁跳过已锁项,同一卡由队列状态互斥。轮询成功后标记完成并出队;可恢复失败按既有策略重试,超过策略标记失败并保留安全失败原因。入队、领取、每次失败、重试、完成和失败出队均记录触发来源、操作来源、时间和结果;仅具有既有轮询任务权限的后台账号可查询记录。
|
||||
|
||||
#### Scenario: 普通轮询遇到优先项
|
||||
- **WHEN** 普通轮询准备处理一张存在活动或已领取优先项的卡
|
||||
- **THEN** 普通轮询跳过该卡,直到优先项完成或失败出队
|
||||
9
openspec/changes/add-priority-polling-queue/tasks.md
Normal file
9
openspec/changes/add-priority-polling-queue/tasks.md
Normal file
@@ -0,0 +1,9 @@
|
||||
## 1. 自动入队与执行
|
||||
- [ ] 1.1 追踪新购生效、过期续购生效、流量用尽加油包生效、可靠事件、普通轮询和运营商调用链路。
|
||||
- [ ] 1.2 新增队列、来源事实和执行审计的成对迁移、活动项唯一索引、模型与查询权限。
|
||||
- [ ] 1.3 在三种套餐生命周期成功事件后发布可靠入队事件;实现同卡合并、回调/任务重放幂等和禁止人工入队。
|
||||
- [ ] 1.4 实现锁定领取、普通轮询排除、套餐/流量/状态优先轮询、失败恢复和出队审计。
|
||||
|
||||
## 2. 验证
|
||||
- [ ] 2.1 验证三种触发、失败订单不入队、重复回调、并发合并、普通互斥、失败重试和权限。
|
||||
- [ ] 2.2 运行 `gofmt -w`、`go build ./cmd/api ./cmd/worker`、`go run cmd/gendocs/main.go`、`openspec validate add-priority-polling-queue --strict` 和 `openspec doctor --json`;自动化测试按项目决策为 N/A。
|
||||
Reference in New Issue
Block a user