All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.shoulder.batch.progress.BatchProgressRecord Maven / Gradle / Ivy

Go to download

Shoulder 扩展-批处理模块,提供批量数据导入、导出、异步校验、导入历史记录管理等能力。

The newest version!
package org.shoulder.batch.progress;

import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.function.BiConsumer;


/**
 * 批量处理进度模型 record类
 * 

* 没有进度条、预计剩余时间,已使用时间的等,这些可以通过给的字段计算,因此不给 * 线程不安全:适用于单机单线程管理进度的模块,绝大多数场景足够 * * @author lym * fixme 完成了 stopTime 为空,显示还剩1个未完成 */ @Data @NoArgsConstructor //@javax.annotation.concurrent.NotThreadSafe public class BatchProgressRecord implements Serializable, Progress { private static final long serialVersionUID = 1L; /** * 批处理任务id */ private String id; /** * 任务开始执行的时间 */ private LocalDateTime startTime; /** * 如:上次运行时已经完成一部分了,在这里体现,用于预估结束时间 */ private int alreadyFinishedAtStart; /** * 任务停止时间 */ private LocalDateTime stopTime; /** * 任务需要处理的记录总数 */ private int total; /** * 任务已经处理的记录数 */ private int processed; /** * 成功数 */ private int successNum; /** * 失败数 */ private int failNum; /** * 状态: * 0 未开始,1 执行中,2 异常结束,3正常结束 */ public int status; private Map ext; public void start() { status = ProgressStatusEnum.RUNNING.getCode(); startTime = LocalDateTime.now(); if (total == 0) { finish(); } } @Override public void failStop() { status = ProgressStatusEnum.EXCEPTION.getCode(); stopTime = LocalDateTime.now(); } @Override public void finish() { assert total == processed; status = ProgressStatusEnum.FINISHED.getCode(); stopTime = LocalDateTime.now(); } public boolean hasFinish() { return status > ProgressStatusEnum.RUNNING.getCode(); } /** * 已经花费的时间 * * @return 已经花费的时间 */ public long calculateProcessedTime() { if (status == ProgressStatusEnum.WAITING.getCode()) { return 0; } if (hasFinish()) { if (stopTime == null) { stopTime = LocalDateTime.now(); } return Duration.between(startTime, stopTime).toMillis(); } return Duration.between(startTime, LocalDateTime.now()).toMillis(); } /** * 估算当前进度 * * @return 进度 */ public float calculateProgress() { if (hasFinish()) { return 1; } // 即将完成 99% return this.processed == total ? 0.999F : this.processed / (float) total; } /** * 估算剩余所需时间 * * @return 剩余所需时间 ms */ public long calculateTimeLeft() { if (hasFinish()) { return 0L; } if (processed - alreadyFinishedAtStart <= 0) { // 默认 99 天 return Duration.ofDays(99).toMillis(); } return (calculateProcessedTime() / (processed - alreadyFinishedAtStart) * (total - processed)); } @Override public String toString() { return "BatchProgress{" + "batchId='" + id + '\'' + ", total=" + total + ", processed=" + processed + ", startTime=" + startTime + ", status=" + status + '}'; } public void addSuccess(int successNum) { this.successNum += successNum; addProcessed(successNum); } public void addFail(int failNum) { this.failNum += failNum; addProcessed(failNum); } private void addProcessed(int processedNum) { this.processed += processedNum; if (processed == total) { finish(); } } @Override public BatchProgressRecord getBatchProgress() { return this; } @Override public void finishPart(int partIndex) { addSuccess(1); } @Override public void setOnFinishCallback(BiConsumer onFinishedCallback) { throw new UnsupportedOperationException("static record object not supported!"); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy