收口七月卡状态回调与系列授权兼容契约
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
完成运营商实名回调、业务事件观测序列与受控配置装配,同时恢复 UR43 已交付的 packages[].remove 字段及旧响应兼容,统一更新 OpenSpec、OpenAPI 和交付文档。 Constraint: 七月测试环境里程碑不新增或运行自动化测试 Rejected: 以必填 operation_type 替换 packages[].remove | 会破坏已交付前端契约 Confidence: high Scope-risk: broad Directive: 后续修改系列套餐管理接口必须保持 packages[].remove 和 ShopSeriesGrantResponse 兼容 Tested: go run ./cmd/gendocs;go build -buildvcs=false ./...;openspec validate complete-july-iteration-test-release --strict;git diff --check Not-tested: 按本 Change 约定未运行 go test,真实运营商与 Gateway 联调延期
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/redis/go-redis/v9"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/infrastructure/cardtrafficlock"
|
||||
"github.com/break/junhong_cmp_fiber/internal/polling"
|
||||
"github.com/break/junhong_cmp_fiber/internal/store/postgres"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||||
@@ -28,7 +29,6 @@ var acquireConcurrencyScript = redis.NewScript(`
|
||||
return current
|
||||
`)
|
||||
|
||||
const cardTrafficSyncLockTTL = 10 * time.Minute
|
||||
const pollingFallbackOperationTimeout = 5 * time.Second
|
||||
|
||||
// pollingFallbackContext 创建轮询兜底操作使用的独立短超时上下文。
|
||||
@@ -47,6 +47,7 @@ type PollingBase struct {
|
||||
iotCardStore *postgres.IotCardStore
|
||||
logger *zap.Logger
|
||||
verboseLog bool
|
||||
trafficLock *cardtrafficlock.Lock
|
||||
}
|
||||
|
||||
// NewPollingBase 创建轮询共享基类
|
||||
@@ -65,6 +66,7 @@ func NewPollingBase(
|
||||
iotCardStore: iotCardStore,
|
||||
logger: logger,
|
||||
verboseLog: verboseLog,
|
||||
trafficLock: cardtrafficlock.New(redisClient),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,26 +107,16 @@ func (b *PollingBase) releaseConcurrency(_ context.Context, taskType string) {
|
||||
}
|
||||
|
||||
// acquireCardTrafficSyncLock 获取卡流量同步锁,避免轮询与手动刷新重复统计同一上游读数。
|
||||
func (b *PollingBase) acquireCardTrafficSyncLock(ctx context.Context, cardID uint) (bool, error) {
|
||||
if b.redis == nil {
|
||||
return true, nil
|
||||
}
|
||||
locked, err := b.redis.SetNX(ctx, constants.RedisCardTrafficSyncLockKey(cardID), "1", cardTrafficSyncLockTTL).Result()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return locked, nil
|
||||
func (b *PollingBase) acquireCardTrafficSyncLock(ctx context.Context, cardID uint) (string, bool, error) {
|
||||
return b.trafficLock.Acquire(ctx, cardID)
|
||||
}
|
||||
|
||||
// releaseCardTrafficSyncLock 释放卡流量同步锁。
|
||||
func (b *PollingBase) releaseCardTrafficSyncLock(_ context.Context, cardID uint) {
|
||||
if b.redis == nil {
|
||||
return
|
||||
}
|
||||
func (b *PollingBase) releaseCardTrafficSyncLock(_ context.Context, cardID uint, token string) {
|
||||
ctx, cancel := pollingFallbackContext()
|
||||
defer cancel()
|
||||
|
||||
if err := b.redis.Del(ctx, constants.RedisCardTrafficSyncLockKey(cardID)).Err(); err != nil {
|
||||
if err := b.trafficLock.Release(ctx, cardID, token); err != nil {
|
||||
b.logger.Warn("释放卡流量同步锁失败", zap.Uint("card_id", cardID), zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user