Skip to content

任务 - 基础任务类型

CODE 脚本任务

脚本任务对应的实现类是CodeTask 本身没有任何属性 ,但因为其继承自AbstractTask 所以基类的属性可以直接访问。脚本的任务结果就是执行初始化闭包时的返回结果。

实现类

// 脚本任务的实现类
public class CodeTask extends AbstractTask implements  Self   {
public CodeTask() {
    super("CODE", null);
}
}

声明示例

 // 执行任意groovy脚本代码
t1= CODE {
  "hello" // 返回结果,可返回空
}

使用建议

  • 虽然CODE任务可以编写任何代码,但应该优先采用现有任务实现,如果现有任务无法满足再采用CODE实现,这样中间过程就是可控的。
  • 尽量避免在CODE中编写过于复杂的任务,一些通用复杂逻辑可考虑封装在某个app应用中。
  • 对于复杂的代码要多使用vars做为中间变量,这样出现问题时方便排查。
  • 要确保CODE任务的返回结果是可序列化的,这样流程返回时不会出错。

BOOLE 判断任务

BOOLE任务通常用于处理条件分支,根据返回的truefalse决定进入哪条分支,BOOLE任务块中可执行任意代码但其必须返回布尔类型,不能返回空值或其他类型,布尔任务一般通过 when指令来判断执行。

BOOLE判断任务对应的实现类是BooleTask 本身没有任何属性 ,但因为其继承自AbstractTask 所以其基类的属性可以直接访问。

声明示例

// 条件判断任务
t1= BOOLE {
   // 可执行任意groovy脚本代码
	 true // 必须返回布尔类型,不能返回空
}

注意事项

  • 除返回结果限制外BOOLE任务与CODE其它特性与行为是一至的,所以CODE任务的建议在BOOLE中同样生效。

CASE 多状态任务

CASE多状态任务用于定义一组状态,该任务会计算当前所处状态,然后when指令会根据其状态值进入对应的分支。

声明语法

// 0.状态A 1.状态B 2.状态C
任务名 = CASE {
    状态A = 布尔表达示   // index 0
    状态B = 布尔表达示   // index 1
    状态C = true			 // index 2
    //..
}
  • 状态名称可由用户自行定义,只要符groovy命名规范即可,可以是中文但不能与隐式变量、任务基础属性冲突。
  • 状态值必须是布尔值,用于确定是否处于当前状态。
  • 如果有多个状态同时满足,会根据定义的先后顺序来确认。
  • 至少要有一个状态被满足,否则会报错。
  • CASE任务的结果是一个状态对应的index坐标,该坐标从0开始。when 指令会根据index值选择进入对应流程分支。

实现类

CASE 任务的实现类是CaseTask其之所以可以自定义状态名是基于groovy的propertyMissing拦截机制实现,最终所有状态都保存到了CaseTask#items属性中对应代码如下:

java
@Setter
@Getter
public class CaseTask  extends AbstractTask {
    public CaseTask() {
        super("CASE", null);
    }

    Map<String, Boolean> items = new LinkedHashMap<>(); // 状态存储
}

声明示例

//0.已锁定 1.拉黑 2.正常
帐户状态 = CASE {
    已锁定 = user.isLock
    拉黑 = blacklist.contains(user.id)
    正常 = true
}

上列中如果已锁定拉黑两个状态都不满足就会返回第正常状态的索引2。

使用规范与建议

  • 如果状态名称很复杂可以通过items['状态名'] = true 方式来定义。
  • 状态任务块中除了定义状态也可以写其它代码来计算状态,但要尽量避免使用过于复杂的代码
  • 复杂状态计算时可以利用vars中间变量观察计算过程
  • 建议最后定义一个直接为true的状态,避免所有状态都不成立时出错。

Invoke 调用型任务

调用型任务指调用当前进程之外的服务或资源如HttpTaskSqlTask分别要与http服务以及数据库交互。由于外部服务的不确定性这类任务需要重试、异步处理、调用拦截等机制。所以在ApiFlow中创建了InvokeTask 抽像类它是所有调用型任务的基类,提供了重试、异步处理、调用拦截等机制,这些机制以方法的形式在任务块中进行配置。

InvokeTask 关键代码

public abstract class InvokeTask extends AbstractTask {
		/**
     * 失败重试,失败判别基于invoke方法执行时任何异常。
     * 当某些状态结果为失败时子任务需在invoke实现类中进行判断并throw异常,如http任务中的状态码不等于200。
     * @param count 重试次数
     * @param interval 重试间隔毫秒数
     */
    public void retry(int count, int interval) { }

    /**
     * 执行失败勿略策略
     * @param returnValue 失败时任务的结果,如果该值是一个闭包将返回执行后的结果
     */
    public void useIgnore(Object returnValue) { }

    /**
     * 执行失败中断策略
     * @param returnValue 失败时为整个流程返回一个结果,如果该值是一个闭包将返回执行后的结果
     */
    public void useAbort(Object returnValue) { }

    /**
     * 添加任务执行前监听,在任务初始化之后以及任务执行前触发
     * @param closure 任务执行的闭包
     */
    public void doFirst(Closure<?> closure) {
        closure.setDelegate(this);
        closure.setResolveStrategy(Closure.DELEGATE_FIRST);
    }
     /**
     * 添加结束监听 ,
     * 在任务执行结束后且未出现异常情况下调用。
     * 可用于验证结果、转换封装结果以及修改任务状态
     *
     * @param closure 任务执行的闭包
     */
    public void doLast(Closure<?> closure) {
       closure.setDelegate(this);
       closure.setResolveStrategy(Closure.DELEGATE_FIRST);
    }

}

配置方法说明

以下是调用型任务支持的配置方法:

  • retry 失败重试 参数分别是重试次数与重试间隔毫秒数
  • useIgnore 执行失败勿略策略
  • useAbort 执行失败中断策略
  • doFirst 添加任务执行前监听,在任务初始化之后以及任务执行前触发。可调用多次。
  • doLast 添加结束监听,在任务执行结束后且未出现异常情况下调用。 可用于验证结果、转换封装结果以及修改任务状态等。可调用多次。

HTTP 任务调用配置示例

groovy
t1 = HTTP {
	url="https://qqlykm.cn/api/plateNumber/index"
  retry 3,2000 // 失败重试3次 每次间隔2000毫秒
  useAbort {// 失败时中断整个流程 并返回相应错误码和错误消息。
    [errorCode:"0001", errorMsg:_runtimeError.message]
  }
  doFirst {// 前置调用
      cookies["jwt_token"]="xxxxxx"  //任务执行前统一添加一个cookie
  }
  doLast {//后置调用
     result = result.data // 任务执行后简化参数。
  }
}

注意事项

  • InvokeTask是一个抽象类不可以直接声明。
  • doFirstdoLast 可调用多次且每个都会生效
  • retryuseAbortuseIgnore调用多次后只有最后一次的会生效。

下一步