All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
cn.xnatural.enet.common.task.Step Maven / Gradle / Ivy
package cn.xnatural.enet.common.task;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* 执行步骤/执行节点
* 每个 Step 通过 {@link #next()} 顺序关联
* 核心方法: {@link #run()}
* @param 输入参数类型
* @param 步骤返回值类型
*/
public class Step {
/**
* 执行步骤 的名称
*/
private String name;
/**
* 执行步骤 的说明
*/
private String description;
/**
* 开始执行时间
*/
private long startTime;
/**
* 执行时所需的参数
*/
protected I param;
/**
* 保存执行结果.
*/
protected R result;
/**
* 执行次数
*/
protected AtomicInteger count = new AtomicInteger(0);
/**
* 执行体(当前Step的主要执行逻辑)
*/
protected Function fn;
/**
* 下一个 {@link Step} 判断的函数
* 返回下一个 执行的 {@link Step}
*/
protected Function nextStepFn;
/**
* 如果为true 则 暂停下一个步骤
*/
private boolean suspendNext;
/**
* 所属Task
*/
protected final TaskWrapper task;
/**
* Step 唯一标识
*/
protected String key;
public Step(TaskWrapper task, Function fn, Function nextStepFn) {
this.task = task;
this.fn = fn;
this.nextStepFn = nextStepFn;
}
/**
* nextStep 默认指向 StopStep
* @param task
* @param fn
*/
public Step(TaskWrapper task, Function fn) {
this(task, fn, r -> task.stopStep()); // 默认 指向 StopStep
}
public Step(TaskWrapper task) {
this(task, null);
}
/**
* 不用 输入参数的 Step
* @param
*/
public static class NoInputStep extends Step {
public NoInputStep(TaskWrapper task, Supplier fn, Function nextStepFn) {
super(task, aVoid -> fn.get(), nextStepFn);
}
public NoInputStep(TaskWrapper task, Function fn) {
super(task, fn);
}
public NoInputStep(TaskWrapper task) {
super(task);
}
@Override
public Step setParam(Void param) {
throw new UnsupportedOperationException("NoInputStep not should have input param");
}
}
/**
* 不用 输出参数的 Step
* @param
*/
public static class NoOutStep extends Step {
public NoOutStep(TaskWrapper task, Consumer fn, Function nextStepFn) {
super(task, i -> { fn.accept(i); return null; }, nextStepFn);
}
public NoOutStep(TaskWrapper task, Consumer fn) {
super(task, i -> { fn.accept(i); return null; });
}
public NoOutStep(TaskWrapper task) {
super(task);
}
}
/**
* 任务Task 停止Step,也是最后一个Step
* @param
*/
protected static class StopStep extends NoOutStep {
public StopStep(TaskWrapper task, Consumer fn) {
super(task, fn);
}
public StopStep(TaskWrapper task) { super(task); }
@Override
protected Step next() {
return null;
}
@Override
public Step setNextStepFn(Function nextStepFn) {
throw new UnsupportedOperationException("StopStep not need nextStepFn");
}
}
/**
* 封闭执行的 Task, 没有输入参数, 也没有返回值
*/
public static class ClosureStep extends Step {
public ClosureStep(TaskWrapper task) { super(task); }
public ClosureStep(TaskWrapper task, Consumer fn) {
super(task, aVoid -> { fn.accept(null); return null; });
}
public ClosureStep(TaskWrapper task, Runnable fn, Supplier nextStepSupplier) {
super(task, aVoid -> { fn.run(); return null; }, aVoid -> nextStepSupplier.get());
}
}
/**
* 可重复执行的Step
* @param
* @param
*/
public static class RetryStep extends Step {
/**
* 重试时, 须手动设置为 false
*/
private boolean complete;
private Function retryFn;
private Function paramFn;
public RetryStep(TaskWrapper task) { super(task); }
public RetryStep(TaskWrapper task, Function fn, Function retryFn, Function nextStepFn) {
super(task, fn, nextStepFn);
this.retryFn = retryFn;
}
@Override
protected void process() {
count.getAndIncrement();
if (count.get() > 1) {
if (retryFn == null) throw new NullPointerException(getKey() + ": retryFn is null");
if (paramFn != null) param = paramFn.apply(this); //重新计算输入的参数
result = retryFn.apply(param);
} else {
if (fn == null) throw new NullPointerException(getKey() + ": fn is null");
result = fn.apply(param);
}
complete = true;
}
public RetryStep setRetryFn(Function retryFn) {
this.retryFn = retryFn;
return this;
}
public Function getRetryFn() {
return retryFn;
}
@Override
public boolean isComplete() {
return complete;
}
public RetryStep setComplete(boolean complete) {
this.complete = complete;
return this;
}
/**
* 重新执行
*/
public final void reRun() {
complete = false;
// task.currentStep(): 即被暂停的Step 有可能 不等于 this.
// 比如: 一个Task 中有 Step1, Step2, 当 Step2调了suspendNext(), 但之后Step1 调了此方法即ReRun().
// 那么, 当Step1 reRun 执行完后Step2 却是 suspendNext 状态. 所以 这里, 要先把 被暂停的Step 的 suspendNext 设置为false
if (task.currentStep() != this) task.currentStep().suspendNext = false;
task.currentStep(this);
if (isWaitingNext()) continueNext();
else task.trigger();
}
/**
* 参数获取函数,
* 因为RetryStep可能每次的参数不一样
* @param paramFn
* @return
*/
public RetryStep paramFn(Function paramFn) {
this.paramFn = paramFn;
param = paramFn.apply(this);
return this;
}
@Override
public Step setParam(I param) {
throw new UnsupportedOperationException("Please use method paramFn");
}
}
/**
* Step执行
* @return 下一个执行Step
*/
public final Step run() {
startTime = System.currentTimeMillis();
process();
// endTime
return next();
}
/**
* @return 如果 返回 null , 应该是 任务结束 或 应该是 任务暂停
*/
protected Step next() {
if (task.isShouldStop()) return task.stopStep();
if (suspendNext) return null;
return (nextStepFn == null ? null : nextStepFn.apply(result));
}
/**
* 调用执行函数
*/
protected void process() {
if (fn == null) throw new NullPointerException(getKey() + ": fn is null");
// 如果已执行过了 则直接返回
if (count.incrementAndGet() > 1) {
task.log.error("Step被重复执行, Task被强制Stop!!!");
task.shouldStop();
return;
}
result = fn.apply(param);
if (this instanceof StopStep) {
task.stopped.compareAndSet(false, true);
}
}
/**
* 挂起/暂停
* 等待
*/
public final void suspendNext() {
suspendNext = true;
}
/**
* 是否被 暂停 中
* @return
*/
public final boolean isWaitingNext() {
return suspendNext;
}
/**
* 恢复执行
*/
public final void continueNext() {
suspendNext = false;
task.trigger();
}
public String getKey() {
if (key == null) {
key = task.getKey() + " Step: " + name + "";
}
return key;
}
public boolean isComplete() {
return count.get() >= 1;
}
public Step setParam(I param) {
this.param = param;
return this;
}
public Step setNextStepFn(Function nextStepFn) {
this.nextStepFn = nextStepFn;
return this;
}
public Function getNextStepFn() {
return nextStepFn;
}
public Step setFn(Function fn) {
this.fn = fn;
return this;
}
public Function getFn() {
return fn;
}
public final R getResult() {
return result;
}
public String getName() {
return name;
}
public Step setName(String name) {
this.name = name;
return this;
}
public String getDescription() {
return description;
}
public Step setDescription(String description) {
this.description = description;
return this;
}
public TaskWrapper getTask() {
return task;
}
}