数据传递

流程(Flow)中的多个状态(State)之间传递数据的方式与函数式编程语言相似。云工作流的状态可类比于编程中的函数,它接受输入并返回输出,输出结果存储在上下文中。本文将介绍数据传递的基本概念及其使用示例。

基本概念

云工作流的状态(State)之间可以进行组合嵌套,单个状态(State)运行过程中,其所处的环境中一些数据称为上下文。数据分类如下:

  • 流程数据:流程(Flow)的名称、地域;组成流程的各个状态(State)名称;流程执行过程中依赖的访问角色等信息;

  • 执行数据:执行(Execution)的名称、执行输入;执行过程中当前状态(State)的输入、输出;执行中生成的用于回调的Token信息,以及执行过程中状态(State)发生错误之后,产生的错误信息,针对错误处理的重试次数等信息。

数据访问

与流程和流程执行相关的数据,无论是静态数据,还是动态数据,您都通过系统提供的$Context表达式来访问相关的数据,Context中包含的数据内容如下:

{
  "Execution": {
    "Name": "String",
    "Input": {},
    "RoleArn": "String"
  },
  "Current": {
    "Name": "String",
    "Input": {},
    "Output": {},
    "Error": {
      "Code": "String",
      "Detail": "String"
    },
    "RetryCount": "Number",
    "TaskToken": "String"
  }
}

Context可用于下面场景的数据构造:

  • 输入输出构造器。详细信息,请参见输入和输出

  • 迭代(Map)状态中的ItemsPath字段,例如$Context.Current.Input

  • 选择(Choice)状态中的Condition字段,例如$Context.Current.Input.Size>=1024

  • 错误处理信息判断,例如$Context.Current.Error.Code$Context.Current.Error.Detail

  • 任务回调Token 传递,例如$Context.Current.TaskToken

为了方便用户使用,云工作流提供两个使用频率较高的快捷方式$Input$Output,您可以使用其快速访问当前节点的输入和输出。

  • $Input等价于$Context.Current.Input

  • $Output等价于$Context.Current.Output

数据传递

不同类型的状态(State)之间存在不同的输入输出传输逻辑,在没有输入输出构造器定义的情况下,不同状态(State)的输入输出逻辑如下。

  • 传递(Pass)/成功(Succeed)/失败(Fail)/等待(Wait)状态:接受输入,不做任何处理,直接输出。

  • 选择(Choice)状态:只具备输入能力,会将自身的输入传递到指向的状态。例如,平移传输到Default,或者到某分支判断条件是否成立,如果条件成立,则将输入传输到Next状态。

  • 并行(Parallel)状态:同一份输入,将会被深拷贝后同时传输给多个分支。输出将会被收集为Map[String]Any的形式,其中Key是每个Parallel分支的隐式名称“Branch0~BranchN”,对应Value是每个Parallel分支实际的处理结果。

  • 迭代(Map)状态:同一份输入,将会判断是否为数组或者Map[String]Any,特别强调的是,当Map的输入不是数组时,如果用户也没有通过ItemsPath设置指定要迭代的内容,系统会自动获取Map的Values作为迭代数组;系统将会对该数组进行迭代,每一个数组元素将会作为迭代处理器的输入;Map输出将会被收集为Map[String]Array的形式,其中Key是固定字符串“Items”,Value是由多个迭代结果组成的数组。

  • 任务(Task)状态:接受来自前一个状态或外部数据源的输入数据,在任务脚本中执行具体业务逻辑,使用$Context表达式访问和操作数据,再将任务执行的结果作为输出数据传递给后续状态或存储在外部系统中。

使用示例

Type: StateMachine
Name: DataTransferExample
SpecVersion: v1
StartAt: Step1
States:
  - Type: Pass
    Name: Step1
    Next: Step2
  - Type: Parallel
    Name: Step2
    InputConstructor:
      FieldA: 123
    Branches:
      - StartAt: Pass1
        States:
          - Type: Pass
            Name: Pass1
            End: true
      - StartAt: Pass2
        States:
          - Type: Pass
            Name: Pass2
            End: true
    Next: Step3
  - Type: Pass
    Name: Step3
    End: true

以上示例中,在Parallel类型的Step2状态中使用输入构造器,构造了包含一个属性的JSONObject,其中属性FieldA为123。 该输入被默认传输给ParallelBranch #0与ParallelBranch #1。以其中一个Branch为例,在ParallelBranch #0中,输入被传输给Pass1,站在Pass1运行完成的角度,上下文数据如下所示。

{
  "Execution": {
    "Name": "xxxx-xxxx-xxxx-xxxx",
    "Input": {},
    "RoleArn": "xxxx"
  },
  "Current": {
    "Name": "Pass1",
    "Input": {
      "FieldA": 123
    },
    "Output": {
      "FieldA": 123
    },
    "Error": null,
    "RetryCount": 0
  }
}