realname: verbose log 移入 gateway 块内,避免 gateway=nil 时输出零值 carddata: 添加 && h.gateway != nil 门卫,确保仅 gateway 查询成功时输出 package: verbose log 在 freshCard 加载后、EvaluateAndAct 之前输出 protect: 引入 actionTaken 变量,字段名 network_status → network_status_at_check,新增 action_taken Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
90 lines
3.1 KiB
Go
90 lines
3.1 KiB
Go
package task
|
||
|
||
import (
|
||
"context"
|
||
"time"
|
||
|
||
"github.com/hibiken/asynq"
|
||
"go.uber.org/zap"
|
||
|
||
iot_card_svc "github.com/break/junhong_cmp_fiber/internal/service/iot_card"
|
||
"github.com/break/junhong_cmp_fiber/internal/store/postgres"
|
||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||
)
|
||
|
||
// PollingPackageHandler 套餐检查任务处理器
|
||
// 职责:触发 EvaluateAndAct 检查套餐状态并判断停复机
|
||
// 不做:直接停复机决策,委托给 StopResumeService.EvaluateAndAct
|
||
// 注:套餐状态由 PackageActivationHandler/DataResetHandler/UsageService 维护,
|
||
// 本 Handler 无需查 Gateway,只负责周期性触发再评估。
|
||
type PollingPackageHandler struct {
|
||
base *PollingBase
|
||
iotCardStore *postgres.IotCardStore
|
||
stopResumeSvc iot_card_svc.StopResumeServiceInterface
|
||
}
|
||
|
||
// NewPollingPackageHandler 创建套餐检查任务处理器
|
||
func NewPollingPackageHandler(
|
||
base *PollingBase,
|
||
iotCardStore *postgres.IotCardStore,
|
||
stopResumeSvc iot_card_svc.StopResumeServiceInterface,
|
||
) *PollingPackageHandler {
|
||
return &PollingPackageHandler{
|
||
base: base,
|
||
iotCardStore: iotCardStore,
|
||
stopResumeSvc: stopResumeSvc,
|
||
}
|
||
}
|
||
|
||
// Handle 处理套餐检查任务
|
||
func (h *PollingPackageHandler) Handle(ctx context.Context, t *asynq.Task) error {
|
||
startTime := time.Now()
|
||
|
||
cardID, ok := parseTaskPayload(t.Payload(), h.base.logger)
|
||
if !ok {
|
||
return nil
|
||
}
|
||
|
||
if !h.base.acquireConcurrency(ctx, constants.TaskTypePollingPackage) {
|
||
h.base.logger.Debug("并发已满,重新入队", zap.Uint("card_id", cardID))
|
||
return h.base.requeueCard(ctx, cardID, constants.TaskTypePollingPackage)
|
||
}
|
||
defer h.base.releaseConcurrency(ctx, constants.TaskTypePollingPackage)
|
||
|
||
if _, cacheErr := h.base.getCardWithCache(ctx, cardID); cacheErr != nil {
|
||
if isNotFound(cacheErr) {
|
||
return nil
|
||
}
|
||
h.base.logger.Error("获取卡信息失败", zap.Uint("card_id", cardID), zap.Error(cacheErr))
|
||
h.base.updateStats(ctx, constants.TaskTypePollingPackage, false, time.Since(startTime))
|
||
return h.base.requeueCard(ctx, cardID, constants.TaskTypePollingPackage)
|
||
}
|
||
|
||
if h.stopResumeSvc != nil {
|
||
freshCard, loadErr := h.iotCardStore.GetByID(ctx, cardID)
|
||
if loadErr == nil {
|
||
h.base.logger.Info("套餐检查:执行停复机评估",
|
||
zap.Uint("card_id", cardID),
|
||
zap.Int("network_status", freshCard.NetworkStatus),
|
||
zap.String("stop_reason", freshCard.StopReason))
|
||
if h.base.verboseLog {
|
||
h.base.logger.Info("套餐检查详情",
|
||
zap.Uint("card_id", cardID),
|
||
zap.String("iccid", freshCard.ICCID),
|
||
zap.Int("network_status", freshCard.NetworkStatus),
|
||
zap.String("stop_reason", freshCard.StopReason))
|
||
}
|
||
if evalErr := h.stopResumeSvc.EvaluateAndAct(ctx, freshCard); evalErr != nil {
|
||
h.base.logger.Warn("套餐检查后停复机评估失败",
|
||
zap.Uint("card_id", cardID), zap.Error(evalErr))
|
||
}
|
||
} else {
|
||
h.base.logger.Warn("套餐检查:加载卡信息失败",
|
||
zap.Uint("card_id", cardID), zap.Error(loadErr))
|
||
}
|
||
}
|
||
|
||
h.base.updateStats(ctx, constants.TaskTypePollingPackage, true, time.Since(startTime))
|
||
return h.base.requeueCard(ctx, cardID, constants.TaskTypePollingPackage)
|
||
}
|