package cn.lihu.jh.module.ecg.service.queue; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.annotation.Resource; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * 「自动补人」周期兜底任务。 * *
现场反馈:运动试验签到后出现该现象(低频检查项目,执行器空闲 ⇒ * 分流任务必然跑在事务提交之前,见 {@code QueueServiceImpl#runAfterCommit})。 * *
用独立的单线程守护调度器,**不占用** {@code DynamicSchedulingConfig} 里 * 那个只有 1 个线程的 cron 池(避免影响开诊/闭诊/每日重置任务)。 */ @Component @Slf4j public class QueueAutoRefillJob { /** 补人间隔(秒) */ private static final long INTERVAL_SECONDS = 60L; /** 启动后首次延迟(秒):避开启动阶段(此时还没开诊、工位也没装载完) */ private static final long INITIAL_DELAY_SECONDS = 60L; @Resource private QueueService queueService; private ScheduledExecutorService scheduler; @PostConstruct public void start() { scheduler = Executors.newSingleThreadScheduledExecutor(r -> { Thread t = new Thread(r, "ecg-queue-auto-refill"); t.setDaemon(true); return t; }); scheduler.scheduleWithFixedDelay(() -> { try { // 异步投递到 QueueServiceImpl 的串行执行器;这里只负责"按时踹一脚" queueService.startHurryUpAll(); } catch (Exception e) { log.error("[QueueAutoRefillJob] 周期补人触发异常(下一轮继续)", e); } }, INITIAL_DELAY_SECONDS, INTERVAL_SECONDS, TimeUnit.SECONDS); log.info("[QueueAutoRefillJob] 已启动:每 {} 秒兜底触发一次「全体工位自动补人」" + "(门闸不变:未开诊/停止候诊/候诊区已满 时不会补人)", INTERVAL_SECONDS); } @PreDestroy public void stop() { if (null != scheduler) { scheduler.shutdownNow(); scheduler = null; } } }