记一次定时补全信息的CompletableFuture多线程HTTP调用


@Component
public class ReplenishIncompleteEmrScheduler extends RestSdkSupport {
    private static final Logger logger = LoggerFactory.getLogger(ReplenishIncompleteEmrScheduler.class);
    @Autowired
    ElectronicMedicalRecordService electronicMedicalRecordService;
    @Autowired
    ConnectService connectService;
    @Autowired
    EmrParserAdapter emrParserAdapter;

    private String emrUrl;

    @Value("${server.port}")
    private String port;
    @Autowired
    private EmrIntegrityRecordsService emrIntegrityRecordsService;
    //是否更新电子病历数据
    private static final String BackFill_YES = "1";

    // 定时任务执行器
    private final ScheduledExecutorService scheduledExecutorService
            = Executors.newScheduledThreadPool(1, new NamedThreadFactory("补全定时器", true));

    private ScheduledFuture<?> sendFuture = null;
    //调用间隔10分钟
    private static final int monitorInterval = 10 * 1;
    //启动间隔1分钟
    private static final int beginMonitorInterval = 1;
    //未完成标识
    private static final String inComplete = "0";

    private static final String defaultToken = HealthConst.token_apiself;
    //削峰,初始200,超过放入队列,再超过800起新线程,采用默认AbortPolicy策略,线程数超过2000抛异常
    private final Executor executor = new ThreadPoolExecutor(200, 2000,
            60L, TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(800));
    //初步测试没有压力,速度最快,没有线程上限
//    private final Executor executor = Executors.newCachedThreadPool();

    //单例模式
    private ReplenishIncompleteEmrScheduler() {
    }

    @Override
    protected Class getLoggerClass() {
        return ReplenishIncompleteEmrScheduler.class;
    }

    private static ReplenishIncompleteEmrScheduler instance = null;

    public static synchronized ReplenishIncompleteEmrScheduler getInstance() {
        if (null == instance) {
            instance = new ReplenishIncompleteEmrScheduler();
        }
        return instance;
    }
    @PostConstruct
    public void init() {
        //scheduleWithFixedDelay间隔时间从上次执行结束开计,不用考虑重复问题
        sendFuture = scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
            public void run() {
                try {
                    syncEmr();
                } catch (Throwable t) { // 防御性容错
                    logger.error("Unexpected error occur at send statistic, cause: " + t.getMessage(), t);
                }
            }
        }, beginMonitorInterval, monitorInterval, TimeUnit.MINUTES);
    }

    public void syncEmr() {
        
        List<String> eventList = connectService.getEventHaveingLeaveDateGt15();
        QueryParam queryParam = QueryParamAsPO.build()
                .where(EmrIntegrityRecordsPO.Property.complete, inComplete)
                .and(EmrIntegrityRecordsPO.Property.groupId,"not",HosGroupEnum.leyue.getGroupId())
                .lt(EmrIntegrityRecordsPO.Property.obtainNum, 6 * 24 * 30 * 12);
        List<EmrIntegrityRecordsPO> incompleteList = emrIntegrityRecordsService.select(queryParam, EmrIntegrityRecordsPO.class);
        logger.info("定时任务取得不完整的XX数为:{}", incompleteList.size());
        if (incompleteList.size() > 0 && incompleteList != null) {
            //去除XX时间大于15天的数据
            List<EmrIntegrityRecordsPO> toDolist = incompleteList.stream().filter(
                    event -> !eventList.contains(event.getEventId())
            ).collect(Collectors.toList());
            logger.info("定时任务待更新的XX数为:{}", toDolist.size());

            if (null != toDolist && toDolist.size() > 0) {
                //存放处理结果
                List<Map<String, String>> list = new ArrayList<>();

                //调用API
                List<CompletableFuture<Map<String, String>>> futures = toDolist.stream().map(event -> CompletableFuture.supplyAsync(
                        () -> {
                            Map<String, String> resultMap = new HashMap<String, String>() {
                            };
                            try {
                                String result = doHttpPost(event.getEventId());
                                logger.info("定时同步完成,任务编号eventId:{},返回结果:{}", event.getEventId(), result);
                                resultMap.put(event.getEventId(), result);
                                list.add(resultMap);
                                return resultMap;
                            } catch (Exception e) {
                                logger.error("定时同步失败,任务编号eventId:{};异常信息:{}", event.getEventId(), e);
                                resultMap.put(event.getEventId(), "定时同步失败:" + e);
                            } finally {
                                return resultMap;
                            }
                        }
                        , executor)
                ).collect(Collectors.toList());
                //如果以后有调用结果存库需求,可把resultList存库
                List resultList = futures.stream().map(CompletableFuture::join).collect(Collectors.toList());
                logger.info("此次定时更新全部已完成");
            } else {
                logger.info("定时任务没有需要同步的任务");
            }
        }
    }

    /**
     * 发起httpPost请求
     *
     * @return 请求响应信息 可能为 null
     */
    private String doHttpPost(String eventId) throws Exception {
        EmrReqByEvent emrReqByEvent = EmrReqByEvent.build().setEventId(eventId).setBackFill(BackFill_YES);
        String ip = InetAddress.getLocalHost().getHostAddress();
        emrUrl = "http://" + ip + ":" + port + "/emr/api/medicalrecord/completion";
        return super.post(emrUrl, defaultToken, emrReqByEvent, String.class).asDataIfSuccess();
    }

    public void destroy() {
        if (sendFuture != null) {
            logger.info("关闭定时功能");
            sendFuture.cancel(true);
        }
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值