jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/QueueAutoRefillJob.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,80 @@ 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; /** * ãèªå¨è¡¥äººã卿å åºä»»å¡ã * * <h3>为ä»ä¹éè¦å®</h3> * åæµï¼{@code æéä¸(10) â åè¯ä¸(20)}ï¼åæ¬æ¯**纯äºä»¶é©±å¨**çï¼åªå¨ä¸é¢è¿äºæ¶æºè·ä¸æ¬¡ï¼ * <ul> * <li>ç¾å°æ¶ ââ {@code AppointmentServiceImpl#appoitmentConfirm} â {@code queue()} â {@code startHurryUpOneCheckType}</li> * <li>å»çå ¥åº§ / æ¢å¤æ¥è¯ / æå¨å¼è¯ / å«å· / æ£æ¥å®æ ââ åèª {@code startHurryUpOneBed}</li> * <li>å¼è¯ · æå¡éå¯ Â· è¯å®¤éç½® ââ {@code startBedReload} éç {@code hurryupAllBed}</li> * </ul> * 䏿¦ææ¬¡è§¦å没æè·å°ï¼äºå¡æªæäº¤å°±æ¥åºãæ§è¡å¨å¼å¸¸ãæå¡å好å¨éå¯ã * å·¥ä½å½æ¶è¿æ²¡è¿åæµéåâ¦â¦ï¼ï¼æ£è å°±ä¼**æ°¸è¿**åå¨ãæéä¸(æªåé å·¥ä½)ãï¼ * åªè½ç±å»çå¨å·¥ä½å°æå·¥ç¹ãæå ¥ãã * * <p>ç°åºåé¦ï¼è¿å¨è¯éªç¾å°ååºç°è¯¥ç°è±¡ï¼ä½é¢æ£æ¥é¡¹ç®ï¼æ§è¡å¨ç©ºé² â * 念任å¡å¿ ç¶è·å¨äºå¡æäº¤ä¹åï¼è§ {@code QueueServiceImpl#runAfterCommit}ï¼ã * * <h3>åäºä»ä¹</h3> * æ¯ {@value #INTERVAL_SECONDS} ç§å¯¹**ææå¼è¯å·¥ä½**触å䏿¬¡èªå¨è¡¥äººã * åªæ¯"å¤è·ä¸æ¬¡å¹çç补人"ï¼é¨é¸ï¼æªå¼è¯ / 忢åè¯ / åè¯åºå·²æ»¡ï¼å ¨é¨ä¿æä¸åï¼ * å æ¤ä¸ä¼æ¹åæ¢æä¸å¡è§åï¼åªæ"æ¼ç½çæéæ£è "å¨ 1 åéå è¡¥ä¸ã * * <p>ç¨ç¬ç«çå线ç¨å®æ¤è°åº¦å¨ï¼**ä¸å ç¨** {@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; } } } jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/QueueService.java
@@ -67,6 +67,18 @@ java.util.Map<String, Object> hurryUpNow(Long roomId, String bedNo); void startHurryUpOneCheckType(Integer checkType); /** * å åºï¼å¯¹**ææ**å¼è¯å·¥ä½è§¦å䏿¬¡èªå¨è¡¥äººï¼çä»·äºé个 {@link #startHurryUpOneBed}ï¼ã * * <p>ç± {@code QueueAutoRefillJob} 卿æ§è°ç¨ï¼åæµæ¬èº«æ¯"äºä»¶é©±å¨"ç * ï¼ç¾å° / å ¥åº§ / å¼è¯ / å«å· / 宿å触å䏿¬¡ï¼ï¼ä»»ä½ä¸æ¬¡è§¦å没è·å°æè·æ©äº * ï¼ä¾å¦ç¾å°äºå¡è¿æ²¡æäº¤ãæ§è¡å¨å¼å¸¸ï¼ï¼æ£è å°±ä¼ä¸ç´åå¨ãæéä¸ãï¼ * åªè½ç±å»çæå·¥ãæå ¥ãã卿å åºä¿è¯è¿ç§æ¼ç½æå¤ 1 åé就被补ä¸ã * * <p>é¨é¸ä¸åï¼æªå¼è¯ / 忢åè¯ / åè¯åºå·²æ»¡ æ¶ç §æ ·ä¸ä¼è¡¥äººã */ void startHurryUpAll(); void startBedReload(); void startResetRoom(Boolean needCloseBed); MonitorInfoVO getMonitorInfo(); jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/QueueServiceImpl.java
@@ -22,6 +22,8 @@ import org.apache.cxf.common.util.CollectionUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionSynchronization; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.validation.annotation.Validated; import cn.lihu.jh.module.ecg.dal.dataobject.room.RoomDO; @@ -316,9 +318,45 @@ @Override public void startHurryUpOneBed(Long roomId, String bedNo) { singleThreadExecutor.execute(() -> { queueServiceTxFunctions.hurryupOneBed(roomId, bedNo); }); // ã缺é·ä¿®å¤ãå¿ é¡»çäºå¡æäº¤ååè·ï¼è§ runAfterCommit ç说æ runAfterCommit(() -> singleThreadExecutor.execute(() -> { try { queueServiceTxFunctions.hurryupOneBed(roomId, bedNo); } catch (Exception e) { // åå®ç°ä¸æè·ï¼å¼å¸¸åªçå¨å·¥ä½çº¿ç¨éï¼æ¥å¿ä¸æ¡é½æ²¡æï¼ç°åºæ ä»ææ¥ log.error("[hurryupOneBed] èªå¨è¡¥äººæ§è¡å¼å¸¸. å·¥ä½={}/{}ï¼ä¸å½±å主æµç¨ï¼ä¸ä¸è½®ä¼éè¯ï¼", roomId, bedNo, e); } })); } /** * æã触åèªå¨åæµãæ¨è¿å°**äºå¡æäº¤ä¹å**åæ§è¡ï¼ä¸å¨äºå¡éåç´æ¥æ§è¡ã * * <p>ã缺é·ä¿®å¤Â·ç°åºåé¦ãè¿å¨è¯éªç¾å°åï¼æ£è ä¸ç´åå¨å»çå·¥ä½å°ç * ãæ¬è¯å®¤æéä¸ï¼æªåé å·¥ä½ï¼ãï¼å¿ é¡»æå·¥ç¹ãæå ¥ãæè¿åè¯åºã * * <p>åå ï¼{@link #queue} æ¯ {@code @Transactional}ï¼æå ¥ãæéä¸ãè¡ä¹å**ç«å³**æ * 念任å¡ä¸¢ç» {@code singleThreadExecutor}ãå·¥ä½çº¿ç¨ç¨çæ¯**å¦ä¸ä¸ªæ°æ®åºè¿æ¥**ï¼ * READ COMMITTED ä¸çä¸å°ä¸»äºå¡å°æªæäº¤çé£ä¸è¡ â * {@code getFirstWaitingByCheckTypes} è¿å null â è¿æ¬¡åæµä»ä¹é½æ²¡åå°±éåºï¼ * äºå¡æäº¤ååæ²¡æä»»ä½è¡¥å¿ â æ£è æ°¸è¿çå¨ãæéä¸ãã * * <p>为ä»ä¹ä½é¢æ£æ¥é¡¹ç®ï¼è¿å¨è¯éªãé£éçµççï¼å ä¹å¿ ç¶ä¸æãé«é¢çå´"çèµ·æ¥æ£å¸¸"ï¼ * æ§è¡å¨å¹³æ¶ç©ºé²ï¼ä»»å¡è½**ç«å»**æ§è¡ï¼å¿ ç¶æ©äºæäº¤ï¼ï¼é«é¢é¡¹ç®ä»»å¡ä¼æéï¼ * è½®å°æ¶äºå¡å¾å¾å·²ç»æäº¤ï¼äºæ¯ä¾¥å¹¸æåã */ private void runAfterCommit(Runnable task) { if (TransactionSynchronizationManager.isSynchronizationActive()) { TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { @Override public void afterCommit() { task.run(); } }); } else { task.run(); } } @Override @@ -329,9 +367,32 @@ @Override public void startHurryUpOneCheckType(Integer checkType) { singleThreadExecutor.execute(() -> { queueServiceTxFunctions.hurryupOneCheckType(checkType); }); // ã缺é·ä¿®å¤ãå¿ é¡»çäºå¡æäº¤ååè·ï¼è§ runAfterCommit ç说æ runAfterCommit(() -> singleThreadExecutor.execute(() -> { try { queueServiceTxFunctions.hurryupOneCheckType(checkType); } catch (Exception e) { log.error("[hurryupOneCheckType] èªå¨åæµæ§è¡å¼å¸¸. checkType={}ï¼ä¸å½±å主æµç¨ï¼ä¸ä¸è½®ä¼éè¯ï¼", checkType, e); } })); } /** * å åºï¼å¯¹**æå»çå¨åº§**çå·¥ä½è§¦å䏿¬¡èªå¨è¡¥äººï¼ç± {@code QueueAutoRefillJob} 卿è°ç¨ï¼ã * * <p>注æç¨çæ¯ {@code hurryupAllSeatedBeds} è䏿¯ {@code hurryupAllBed}ï¼ * åè 伿æ£è æ¨è¿"å·²å¼é使²¡å»ç"çå·¥ä½ï¼å¨æè·ä¼æ¾å¤§è¯¥å¯ä½ç¨ã */ @Override public void startHurryUpAll() { runAfterCommit(() -> singleThreadExecutor.execute(() -> { try { queueServiceTxFunctions.hurryupAllSeatedBeds(); } catch (Exception e) { log.error("[hurryupAllSeatedBeds] å¨æè¡¥äººæ§è¡å¼å¸¸ï¼ä¸ä¸è½®ç»§ç»ï¼", e); } })); } @Override jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/QueueServiceTxFunctions.java
@@ -665,6 +665,34 @@ } /** * ã卿å åºä¸ç¨ãåªç»**æå»çå¨åº§ï¼DOCTOR_ONï¼**çå·¥ä½è¡¥äººã * * <p>为ä»ä¹ä¸è½ç´æ¥ç¨ {@link #hurryupAllBed()}ï¼å®éåçæ¯ `mapOpeningBed` * ï¼å«ãå·²å¼é使²¡äººãçå·¥ä½ï¼ï¼ä¼ææéæ£è æ¨è¿**没æå»ç**çå·¥ä½åè¯åº ââ * å䏿£æ¥é¡¹ç®æå¤ä¸ªå·¥ä½æ¶ï¼å¦å¸¸è§å¿çµå¾ 116/117/118ï¼ï¼æ£è å¯è½è¢«"åé "å° * ä¸ä¸ªæ²¡äººççå·¥ä½ï¼çæ£å¨åº§çå»çåèçä¸å°ãè¯¥æ¹æ³åæ¬åªå¨å¼è¯/é坿¶è·ä¸æ¬¡ï¼ * è¥æ¹ææ¯åéè·ä¸éï¼è¿ä¸ªå¯ä½ç¨ä¼è¢«æ¾å¤§ãå æ¤å¨æå åºåªè¡¥å¨åº§å·¥ä½ï¼ * ä¸èªå¨åæµéåï¼{@code addBedToRoutingQueue} åªæ¶ DOCTOR_ONï¼çå£å¾ä¿æä¸è´ã */ public void hurryupAllSeatedBeds() { if (0 == openingFlag.get()) return; mapOpeningBed.values().forEach(bedQueueBO -> { // åªè¡¥ãæå»çå¨åº§ãçå·¥ä½ if (!Objects.equals(BedStatusEnum.DOCTOR_ON.getStatus(), bedQueueBO.getStatus())) { return; } // ã忢åè¯ãçå·¥ä½ç´æ¥è·³è¿ï¼hurryupOneBed å 鍿¬æ¥ä¹ä¼è·³è¿ï¼ // è¿éæå夿æ¯ä¸ºäºé¿å æ¯åéå·ä¸æ¡ "[补人] å·¥ä½å¤äºã忢åè¯ã" ç WARNã if (Boolean.TRUE.equals(bedQueueBO.getStopReady())) { return; } hurryupOneBed(bedQueueBO.roomId, bedQueueBO.bedNo); }); } /** * æå»çåè¯çéå塿»¡ */ public void hurryupOneBed(Long roomId, String bedNo) { jh-server/src/main/resources/application-local.yaml
@@ -51,16 +51,15 @@ primary: master datasource: master: url: jdbc:mysql://47.93.127.38:3308/lihu?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X è¿æ¥çç¤ºä¾ # url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai # MySQL Connector/J 5.X è¿æ¥çç¤ºä¾ # url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL è¿æ¥çç¤ºä¾ # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle è¿æ¥çç¤ºä¾ # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true;useUnicode=true;characterEncoding=utf-8 # SQLServer è¿æ¥çç¤ºä¾ # url: jdbc:dm://127.0.0.1:5236?schema=RUOYI_VUE_PRO # DM è¿æ¥çç¤ºä¾ # url: jdbc:kingbase8://127.0.0.1:54321/test # 人大éä» KingbaseES è¿æ¥çç¤ºä¾ # url: jdbc:postgresql://127.0.0.1:5432/postgres # OpenGauss è¿æ¥çç¤ºä¾ username: smartor password: Smartor.2016 # url: jdbc:mysql://127.0.0.1:3308/lihu?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X è¿æ¥çç¤ºä¾ # url: jdbc:mysql://47.93.127.38:3308/lihu?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X è¿æ¥çç¤ºä¾ # username: smartor # password: Smartor.2016 url: jdbc:mysql://127.0.0.1:3306/lihu?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X è¿æ¥çç¤ºä¾ username: root password: sendohill # username: sa # SQL Server è¿æ¥çç¤ºä¾ # password: Jh@2024 # SQL Server è¿æ¥çç¤ºä¾ # username: SYSDBA # DM è¿æ¥çç¤ºä¾ @@ -69,9 +68,13 @@ # password: Jh@2024 # OpenGauss è¿æ¥çç¤ºä¾ slave: # 模æä»åºï¼å¯æ ¹æ®èªå·±éè¦ä¿®æ¹ lazy: true # å¼å¯æå è½½ï¼ä¿è¯å¯å¨é度 url: jdbc:mysql://47.93.127.38:3308/lihu?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X è¿æ¥çç¤ºä¾ username: smartor password: Smartor.2016 # url: jdbc:mysql://127.0.0.1:3308/lihu?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X è¿æ¥çç¤ºä¾ # url: jdbc:mysql://47.93.127.38:3308/lihu?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X è¿æ¥çç¤ºä¾ # username: smartor # password: Smartor.2016 url: jdbc:mysql://127.0.0.1:3306/lihu?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X è¿æ¥çç¤ºä¾ username: root password: sendohill # Redis é ç½®ãRedisson é»è®¤çé 置足å¤ä½¿ç¨ï¼ä¸è¬ä¸éè¦è¿è¡è°ä¼ redis: jh-server/src/main/resources/application.yaml
@@ -3,8 +3,8 @@ name: jh-server profiles: # active: local active: prod active: local # active: prod main: allow-circular-references: true # å 许循ç¯ä¾èµï¼å ä¸ºé¡¹ç®æ¯ä¸å±æ¶æï¼æ æ³é¿å è¿ä¸ªæ åµã