|
@@ -1,6 +1,8 @@
|
|
|
package com.sundata.internalevaluation.calc.model;
|
|
|
|
|
|
-
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import cn.hutool.core.date.TimeInterval;
|
|
|
+import com.sundata.internalevaluation.calc.model.finals.CalcStatus;
|
|
|
import com.sundata.internalevaluation.calc.model.finals.CalcType;
|
|
|
import com.sundata.internalevaluation.calc.model.interfaces.Calc;
|
|
|
import org.slf4j.Logger;
|
|
@@ -12,17 +14,17 @@ import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Objects;
|
|
|
import java.util.StringJoiner;
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
|
+import java.util.concurrent.ExecutionException;
|
|
|
|
|
|
public abstract class CalcUnit implements Calc, Serializable {
|
|
|
private static final Logger log = LoggerFactory.getLogger(CalcUnit.class);
|
|
|
@Serial
|
|
|
private static final long serialVersionUID = 1L;
|
|
|
-
|
|
|
/**
|
|
|
* 计算单元编号
|
|
|
*/
|
|
|
private final String calcCode;
|
|
|
-
|
|
|
/**
|
|
|
* 计算单元名称
|
|
|
*/
|
|
@@ -31,11 +33,18 @@ public abstract class CalcUnit implements Calc, Serializable {
|
|
|
* 计算单元类型
|
|
|
*/
|
|
|
private final CalcType calcType;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算状态
|
|
|
+ */
|
|
|
+ private CalcStatus status = CalcStatus.READY;
|
|
|
/**
|
|
|
* 初始化用属性对象节点
|
|
|
*/
|
|
|
private final Map<String, Object> initContext;
|
|
|
|
|
|
+ private CompletableFuture<CalcResult<String, Object>> resultContextFuture;
|
|
|
+
|
|
|
/**
|
|
|
* 计算结果对象
|
|
|
*/
|
|
@@ -49,10 +58,10 @@ public abstract class CalcUnit implements Calc, Serializable {
|
|
|
/**
|
|
|
* 创建数据单元的绝对对象,对象必须包含如下参数
|
|
|
*
|
|
|
- * @param calcCode 计算对象编号
|
|
|
- * @param calcName 计算对象名称
|
|
|
- * @param calcType 计算类型
|
|
|
- * @param initContext 计算单元初始化参数
|
|
|
+ * @param calcCode 计算对象编号
|
|
|
+ * @param calcName 计算对象名称
|
|
|
+ * @param calcType 计算类型
|
|
|
+ * @param initContext 计算单元初始化参数
|
|
|
*/
|
|
|
public CalcUnit(String calcCode, String calcName, CalcType calcType, Map<String, Object> initContext) {
|
|
|
this.calcCode = calcCode;
|
|
@@ -61,37 +70,61 @@ public abstract class CalcUnit implements Calc, Serializable {
|
|
|
this.initContext = initContext;
|
|
|
}
|
|
|
|
|
|
- public void startCalc(String calculateInstanceNumber, Map<String, Object> context, Map<CalcUnit, CalcResult<String, Object>> sourceResults) {
|
|
|
|
|
|
- if (isCalcFinished(this.calculateInstanceNumber)) { // 如果已经计算过则不再执行计算处理,仅需要通过 initResultContext 初始化 resultContext 对象
|
|
|
+ public CalcResult<String, Object> getResultContextFuture(String calculateInstanceNumber, Map<String, Object> context, Map<CalcUnit, CalcResult<String, Object>> sourceResults) {
|
|
|
+ try {
|
|
|
+ if (this.resultContextFuture != null) {
|
|
|
+ return this.resultContextFuture.get();
|
|
|
+ } else {
|
|
|
+ synchronized (this) {
|
|
|
+ if (this.resultContextFuture == null) {
|
|
|
+ this.resultContextFuture = CompletableFuture.supplyAsync(() -> {
|
|
|
+ this.startCalc(calculateInstanceNumber, context, sourceResults);
|
|
|
+ return this.resultContext;
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ return this.resultContextFuture.get();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (InterruptedException | ExecutionException e) {
|
|
|
+ log.error(e.getMessage(), e);
|
|
|
+ throw new CalcException(calculateInstanceNumber, "计算出现问题,线程级别,请检查处理过程。");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void startCalc(String calculateInstanceNumber, Map<String, Object> context, Map<CalcUnit, CalcResult<String, Object>> sourceResults) {
|
|
|
+ setStatus(CalcStatus.RUNNING);
|
|
|
+ if (isCalcFinished(calculateInstanceNumber)) { // 如果已经计算过则不再执行计算处理,仅需要通过 initResultContext 初始化 resultContext 对象
|
|
|
+ log.info("当前计算节点为:[{}-{}-{}],曾经完成过计算,加载原始计算内容并结束", this.getCalcType(), this.getCalcCode(), this.getCalcName());
|
|
|
initResultContext(calculateInstanceNumber);//计算过
|
|
|
- getCalcUnitInstanceNumber();
|
|
|
+ setStatus(CalcStatus.FINISHED);
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
+ TimeInterval interval = new TimeInterval();
|
|
|
setCalculateInstanceNumber(calculateInstanceNumber);
|
|
|
// String calcUnitInstanceNumber = getCalcUnitInstanceNumber();
|
|
|
- log.debug("计算对象为:{}", this);
|
|
|
- log.debug("计算流水号为:{}",calculateInstanceNumber);
|
|
|
- log.debug("计算参数为: {}", context);
|
|
|
- log.debug("源头节点提供的结果为: {}", sourceResults);
|
|
|
+ log.info("当前计算节点为:[{}-{}-{}],计算流水号为:{}", this.getCalcType(), this.getCalcCode(), this.getCalcName(), calculateInstanceNumber);
|
|
|
+ interval.start();
|
|
|
try {
|
|
|
- log.debug("calcUnitInstanceNumber: {}", calculateInstanceNumber);
|
|
|
- log.debug("startBeforeCalcUnit: {}", calculateInstanceNumber);
|
|
|
this.beforeCalc(context);
|
|
|
- final CalcResult<String, Object> thisResult = new CalcResult<>(calculateInstanceNumber);;
|
|
|
- this.calc(thisResult,calculateInstanceNumber,context, sourceResults);
|
|
|
+ final CalcResult<String, Object> thisResult = new CalcResult<>(calculateInstanceNumber);
|
|
|
+ ;
|
|
|
+ this.calc(thisResult, calculateInstanceNumber, context, sourceResults);
|
|
|
// log.info("计算节点【{}-{}】完成,结果为【{}】",this.getCalcType(),this.getCalcCode(), thisResult);
|
|
|
- if (thisResult.isEmpty()){
|
|
|
- throw new CalcException(calculateInstanceNumber,"请注意,计算过程中必须将 thisResult 结果数据赋值,否则父节点无法正常计算,计算错误的节点为【"+this.toString()+"】");
|
|
|
+ if (thisResult.isEmpty()) {
|
|
|
+ throw new CalcException(calculateInstanceNumber, "请注意,计算过程中必须将 thisResult 结果数据赋值,否则父节点无法正常计算,计算错误的节点为【" + this.toString() + "】");
|
|
|
}
|
|
|
setResultContext(thisResult);// 计算完成需要设置结果
|
|
|
- log.debug("startAfterCalcUnit: {}", calculateInstanceNumber);
|
|
|
this.afterCalc(context);
|
|
|
} catch (CalcException e) {
|
|
|
this.calculateInstanceNumber = null;
|
|
|
log.error("计算失败,恢复计算逻辑: {}", calculateInstanceNumber, e);
|
|
|
+ setStatus(CalcStatus.ERROR);
|
|
|
}
|
|
|
+ setStatus(CalcStatus.FINISHED);
|
|
|
+ log.info("计算节点[{}-{}-{}]计算过程完成,耗时:{}", this.getCalcType(), this.getCalcCode(), this.getCalcName(), DateUtil.formatBetween(interval.interval()));
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -105,12 +138,14 @@ public abstract class CalcUnit implements Calc, Serializable {
|
|
|
/**
|
|
|
* 初始化计算结果的方法,如果已经计算过,在实现过程中,应当在此方法中根据计算流水号重新初始化 resultContext 结果对象,为其他依赖对象做准备
|
|
|
* 若明明计算过本单元但再次计算时没有初始化该对象,则计算依赖出现问题无法定位与处理
|
|
|
+ *
|
|
|
* @param calculateInstanceNumber 计算流水号
|
|
|
*/
|
|
|
public abstract void initResultContext(String calculateInstanceNumber);
|
|
|
|
|
|
/**
|
|
|
* 根据节点配置获取源节点;
|
|
|
+ *
|
|
|
* @return 所有源头节点
|
|
|
*/
|
|
|
public abstract List<CalcUnit> getSourceCalcUnits();
|
|
@@ -130,6 +165,7 @@ public abstract class CalcUnit implements Calc, Serializable {
|
|
|
public CalcResult<String, Object> getResultContext() {
|
|
|
return resultContext;
|
|
|
}
|
|
|
+
|
|
|
public void setResultContext(CalcResult<String, Object> resultContext) {
|
|
|
this.resultContext = resultContext;
|
|
|
}
|
|
@@ -182,4 +218,12 @@ public abstract class CalcUnit implements Calc, Serializable {
|
|
|
.add("resultContext=" + resultContext)
|
|
|
.toString();
|
|
|
}
|
|
|
+
|
|
|
+ public CalcStatus getStatus() {
|
|
|
+ return status;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void setStatus(CalcStatus status) {
|
|
|
+ this.status = status;
|
|
|
+ }
|
|
|
}
|