From 1c389290009514402415828701e7f88bc4d8b578 Mon Sep 17 00:00:00 2001 From: luogw <3132758203@qq.com> Date: Wed, 29 Jul 2026 17:32:12 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A5=97=E9=A2=98=E7=94=9F=E6=88=90=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E8=B6=85=E6=97=B6=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/ClassicPaperTimeoutProperties.java | 15 ++++ .../domain/enums/ClassicPaperStatusEnum.java | 3 +- .../job/ClassicPaperGenerationTimeoutJob.java | 71 +++++++++++++++++++ src/main/resources/application-dev.yml | 7 ++ src/main/resources/application-prod.yml | 14 +++- src/main/resources/application-test.yml | 6 ++ 6 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/project/classicpaper/config/ClassicPaperTimeoutProperties.java create mode 100644 src/main/java/com/project/classicpaper/domain/job/ClassicPaperGenerationTimeoutJob.java diff --git a/src/main/java/com/project/classicpaper/config/ClassicPaperTimeoutProperties.java b/src/main/java/com/project/classicpaper/config/ClassicPaperTimeoutProperties.java new file mode 100644 index 0000000..ec1930a --- /dev/null +++ b/src/main/java/com/project/classicpaper/config/ClassicPaperTimeoutProperties.java @@ -0,0 +1,15 @@ +package com.project.classicpaper.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Data +@Component +@ConfigurationProperties(prefix = "classicpaper.timeout") +public class ClassicPaperTimeoutProperties { + + private int thresholdMinutes = 120; + + private long intervalMs = 300000L; +} diff --git a/src/main/java/com/project/classicpaper/domain/enums/ClassicPaperStatusEnum.java b/src/main/java/com/project/classicpaper/domain/enums/ClassicPaperStatusEnum.java index 26ee051..39204da 100644 --- a/src/main/java/com/project/classicpaper/domain/enums/ClassicPaperStatusEnum.java +++ b/src/main/java/com/project/classicpaper/domain/enums/ClassicPaperStatusEnum.java @@ -10,7 +10,8 @@ public enum ClassicPaperStatusEnum implements HasValueEnum { GENERATING(0, "生成中"), DRAFT(1, "已生成"), CONFIRMED(2, "已固化"), - DISCARDED(3, "已废弃"); + DISCARDED(3, "已废弃"), + FAILED(4,"生成失败"); private final Integer value; private final String desc; diff --git a/src/main/java/com/project/classicpaper/domain/job/ClassicPaperGenerationTimeoutJob.java b/src/main/java/com/project/classicpaper/domain/job/ClassicPaperGenerationTimeoutJob.java new file mode 100644 index 0000000..de56b7c --- /dev/null +++ b/src/main/java/com/project/classicpaper/domain/job/ClassicPaperGenerationTimeoutJob.java @@ -0,0 +1,71 @@ +package com.project.classicpaper.domain.job; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.project.base.config.ScheduledTaskProperties; +import com.project.classicpaper.config.ClassicPaperTimeoutProperties; +import com.project.classicpaper.domain.entity.ClassicPaperSetEntity; +import com.project.classicpaper.domain.enums.ClassicPaperStatusEnum; +import com.project.classicpaper.domain.service.ClassicPaperSetBaseService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.List; + +/** + * 套题组生成超时检测 + * 扫描 status=GENERATING 且 create_time 超过阈值的套题组,标记为 FAILED + * 防止算法侧漏回调导致套题组永久停留在"生成中" + */ +@Service +@Slf4j +public class ClassicPaperGenerationTimeoutJob { + + @Autowired + private ClassicPaperSetBaseService classicPaperSetBaseService; + + @Autowired + private ScheduledTaskProperties taskProps; + + @Autowired + private ClassicPaperTimeoutProperties timeoutProps; + + @Scheduled(fixedRateString = "${classicpaper.timeout.interval-ms:300000}") + public void checkSetTimeout() { + if ("local".equalsIgnoreCase(taskProps.getOwner())) { + return; + } + + Date cutoff = new Date(System.currentTimeMillis() - timeoutProps.getThresholdMinutes() * 60_000L); + + try { + List stale = classicPaperSetBaseService.list( + new LambdaQueryWrapper() + .eq(ClassicPaperSetEntity::getStatus, ClassicPaperStatusEnum.GENERATING.getValue()) + .lt(ClassicPaperSetEntity::getCreateTime, cutoff) + ); + + if (stale.isEmpty()) { + return; + } + + for (ClassicPaperSetEntity set : stale) { + long elapsedMin = (System.currentTimeMillis() - set.getCreateTime().getTime()) / 60_000L; + boolean updated = classicPaperSetBaseService.lambdaUpdate() + .eq(ClassicPaperSetEntity::getId, set.getId()) + .eq(ClassicPaperSetEntity::getStatus, ClassicPaperStatusEnum.GENERATING.getValue()) + .set(ClassicPaperSetEntity::getStatus, ClassicPaperStatusEnum.FAILED.getValue()) + .update(); + + if (updated) { + log.warn(">>> [套题超时] setId={}, createTime={}, elapsed={}min, 标记为生成失败", + set.getId(), set.getCreateTime(), elapsedMin); + } + } + } catch (Exception e) { + log.error(">>> [套题超时] 扫描异常", e); + } + } +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 67fd283..6a4f0f7 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -135,3 +135,10 @@ classicpaper: # 补充任务初始延迟(毫秒),避免高峰期"挤"算法 replenish-delay-ms: 10000 + # 套题生成超时检测 + timeout: + # 生成超时阈值(分钟),超过此时间仍在 GENERATING 则标记为 FAILED + threshold-minutes: 120 + # 检查间隔(毫秒),每 5 分钟扫描一次 + interval-ms: 300000 + diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 49cddc3..434fff7 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -108,4 +108,16 @@ scheduled-task: classicpaper: mock: regenerate-delay-ms: 0 - regenerate-delay-max-ms: 0 \ No newline at end of file + regenerate-delay-max-ms: 0 + # 套题生成超时检测 + timeout: + # 生成超时阈值(分钟),超过此时间仍在 GENERATING 则标记为 FAILED + threshold-minutes: 120 + # 检查间隔(毫秒),每 5 分钟扫描一次 + interval-ms: 300000 +# 简答题异步评分 +scoring: + # 每批最多处理多少道简答题 + batch-size: 5 + # 执行间隔(毫秒),每60秒扫描一次 + interval-ms: 60000 \ No newline at end of file diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index ddef7b9..89c1566 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -109,6 +109,12 @@ classicpaper: # 是否启用真实算法(true=使用算法服务) algorithm: enabled: true + # 套题生成超时检测 + timeout: + # 生成超时阈值(分钟),超过此时间仍在 GENERATING 则标记为 FAILED + threshold-minutes: 120 + # 检查间隔(毫秒),每 5 分钟扫描一次 + interval-ms: 300000 # 简答题异步评分 scoring: # 每批最多处理多少道简答题