49 lines
1.4 KiB
Go
49 lines
1.4 KiB
Go
package weekstar
|
||
|
||
import (
|
||
"context"
|
||
"net/http"
|
||
"strconv"
|
||
"strings"
|
||
"time"
|
||
|
||
"github.com/redis/go-redis/v9"
|
||
)
|
||
|
||
const weekStarRewardRetryPendingTTL = 30 * time.Minute
|
||
|
||
// enqueueRewardRetryTask 把失败发奖记录投递到 Redis Stream,交给 chatapp-cron 执行真正补发。
|
||
func (s *WeekStarService) enqueueRewardRetryTask(ctx context.Context, recordID int64) error {
|
||
streamKey := strings.TrimSpace(s.cfg.WeekStar.RetryStreamKey)
|
||
if streamKey == "" {
|
||
return NewAppError(http.StatusInternalServerError, "retry_stream_not_configured", "week star retry stream is not configured")
|
||
}
|
||
|
||
pendingKey := s.rewardRetryPendingKey(recordID)
|
||
acquired, err := s.repo.Redis.SetNX(ctx, pendingKey, "1", weekStarRewardRetryPendingTTL).Result()
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if !acquired {
|
||
// 已经存在待处理补发任务时直接视为幂等成功,避免重复投递。
|
||
return nil
|
||
}
|
||
|
||
_, err = s.repo.Redis.XAdd(ctx, &redis.XAddArgs{
|
||
Stream: streamKey,
|
||
Values: map[string]any{
|
||
"recordId": recordID,
|
||
},
|
||
}).Result()
|
||
if err != nil {
|
||
_, _ = s.repo.Redis.Del(context.Background(), pendingKey).Result()
|
||
return err
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// rewardRetryPendingKey 返回补发任务去重 key,避免同一条记录被重复提交。
|
||
func (s *WeekStarService) rewardRetryPendingKey(recordID int64) string {
|
||
return strings.TrimSpace(s.cfg.WeekStar.RetryStreamKey) + ":pending:" + strconv.FormatInt(recordID, 10)
|
||
}
|