processPendingTasks 优化,
This commit is contained in:
@@ -139,20 +139,24 @@ public class GameJob {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 从数据库恢复延迟任务队列
|
* 从数据库恢复延迟任务队列
|
||||||
|
* 注:包括已过期的任务,过期任务会在processPendingTasks中立即执行
|
||||||
*/
|
*/
|
||||||
private void recoverPendingTasks() {
|
private void recoverPendingTasks() {
|
||||||
try {
|
try {
|
||||||
List<PendingTask> dbTasks = pendingTaskMapper.selectList(
|
// 数据库中残留的记录都是未执行的(执行成功后会立即删除),全部恢复
|
||||||
new LambdaQueryWrapper<PendingTask>()
|
List<PendingTask> dbTasks = pendingTaskMapper.selectList(null);
|
||||||
.gt(PendingTask::getExecuteTime, LocalDateTime.now()));
|
|
||||||
|
|
||||||
if (dbTasks == null || dbTasks.isEmpty()) {
|
if (dbTasks == null || dbTasks.isEmpty()) {
|
||||||
log.info("无待执行的延迟任务,无需恢复");
|
log.info("无待执行的延迟任务,无需恢复");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
int recovered = 0;
|
||||||
|
int expiredCount = 0;
|
||||||
for (PendingTask dbTask : dbTasks) {
|
for (PendingTask dbTask : dbTasks) {
|
||||||
if (dbTask.getExecuteTime() == null || !dbTask.getExecuteTime().isAfter(LocalDateTime.now())) {
|
if (dbTask.getExecuteTime() == null) {
|
||||||
|
log.warn("跳过executeTime为空的延迟任务: taskId={}", dbTask.getTaskId());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
PendingTaskInfo info = new PendingTaskInfo();
|
PendingTaskInfo info = new PendingTaskInfo();
|
||||||
@@ -163,9 +167,16 @@ public class GameJob {
|
|||||||
info.setDigit(dbTask.getDigit());
|
info.setDigit(dbTask.getDigit());
|
||||||
info.setExecuteTime(dbTask.getExecuteTime());
|
info.setExecuteTime(dbTask.getExecuteTime());
|
||||||
pendingTasks.put(info.getTaskId(), info);
|
pendingTasks.put(info.getTaskId(), info);
|
||||||
|
recovered++;
|
||||||
|
if (!dbTask.getExecuteTime().isAfter(now)) {
|
||||||
|
expiredCount++;
|
||||||
|
log.warn("恢复已过期任务,启动后立即执行: taskId={}, type={}, groupId={}, executeTime={}",
|
||||||
|
dbTask.getTaskId(), dbTask.getType(), dbTask.getGroupId(), dbTask.getExecuteTime());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("延迟任务恢复完成,共恢复 {} 个待执行任务", pendingTasks.size());
|
log.info("延迟任务恢复完成,共恢复 {} 个待执行任务,其中 {} 个已过期将立即执行",
|
||||||
|
recovered, expiredCount);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("恢复延迟任务失败: {}", e.getMessage(), e);
|
log.error("恢复延迟任务失败: {}", e.getMessage(), e);
|
||||||
}
|
}
|
||||||
@@ -784,7 +795,14 @@ public class GameJob {
|
|||||||
*/
|
*/
|
||||||
private boolean onAutoNext(Long groupId) {
|
private boolean onAutoNext(Long groupId) {
|
||||||
try {
|
try {
|
||||||
gameService.startGame(groupId, 0L); // 0L表示系统自动
|
GameRound round = gameService.startGame(groupId, 0L); // 0L表示系统自动
|
||||||
|
if (round == null || round.getId() == null) {
|
||||||
|
log.warn("自动开始下一期失败:startGame未返回局信息, groupId={}", groupId);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 复用与手动流程一致的逻辑:注册roundTasks监控 + 广播开始下注
|
||||||
|
int betWindowSeconds = getConfigInt("bet_window_seconds", 60);
|
||||||
|
onGameStart(round.getId(), groupId, betWindowSeconds);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("自动开始下一期失败: groupId={}, error={}", groupId, e.getMessage());
|
log.error("自动开始下一期失败: groupId={}, error={}", groupId, e.getMessage());
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import com.tailbet.service.IAuditService;
|
|||||||
import com.tailbet.service.IPointsService;
|
import com.tailbet.service.IPointsService;
|
||||||
import com.tailbet.service.IRedPacketService;
|
import com.tailbet.service.IRedPacketService;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -174,11 +175,19 @@ public class RedPacketServiceImpl implements IRedPacketService {
|
|||||||
|
|
||||||
redPacketMapper.updateById(rp);
|
redPacketMapper.updateById(rp);
|
||||||
|
|
||||||
// 如果是游戏红包且已领完,发布开奖事件
|
// 如果是游戏红包且已领完,标记手气王并发布开奖事件
|
||||||
if (isFinished && TYPE_GAME.equals(rp.getType()) && rp.getRoundId() != null) {
|
if (isFinished && TYPE_GAME.equals(rp.getType()) && rp.getRoundId() != null) {
|
||||||
|
// 标记手气王的领取记录 is_lucky=1
|
||||||
|
if (rp.getLuckyUserId() != null) {
|
||||||
|
redPacketRecvMapper.update(null, new LambdaUpdateWrapper<RedPacketRecv>()
|
||||||
|
.eq(RedPacketRecv::getRpId, rpId)
|
||||||
|
.eq(RedPacketRecv::getUserId, rp.getLuckyUserId())
|
||||||
|
.set(RedPacketRecv::getIsLucky, 1));
|
||||||
|
}
|
||||||
eventPublisher.publishEvent(new RedPacketFinishedEvent(
|
eventPublisher.publishEvent(new RedPacketFinishedEvent(
|
||||||
this, rp.getRoundId(), rp.getGroupId(), rp.getId(), rp.getLuckyDigit()));
|
this, rp.getRoundId(), rp.getGroupId(), rp.getId(), rp.getLuckyDigit()));
|
||||||
log.info("游戏红包领完,发布开奖事件: roundId={}, luckyDigit={}", rp.getRoundId(), rp.getLuckyDigit());
|
log.info("游戏红包领完,标记手气王并发布开奖事件: roundId={}, luckyDigit={}, luckyUserId={}",
|
||||||
|
rp.getRoundId(), rp.getLuckyDigit(), rp.getLuckyUserId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加积分
|
// 加积分
|
||||||
|
|||||||
Reference in New Issue
Block a user