Skip to content

parallel task survey

wt_better edited this page Dec 21, 2023 · 2 revisions

Seata Saga 状态机执行目前只支持串行化,因此本次 PR 是主要是通过 Fork 和 Join 两种状态来实现状态机的并行能力。其中,Fork代表并行分支的开始,Join代表并行分支的结束。

设计目标

  1. [KR1] 执行方式兼容:需要保证扩展的新任务支持已有的执行方式:同步、异步、循环、并行。
  2. [KR2] 合理补偿:需要保证扩展的新任务可以被合理的补偿。
  3. [KR3] 幂等性:由于有重试机制,需要保证任务调用时的幂等性。
  4. [KR4] 单测覆盖:对扩展的新任务进行功能测试的全覆盖。

相关工作

AWS Step Function

{
  "Comment": "Parallel Example.",
  "StartAt": "LookupCustomerInfo",
  "States": {
    "LookupCustomerInfo": {
      "Type": "Parallel",
      "End": true,
      "Branches": [
        {
         "StartAt": "LookupAddress",
         "States": {
           "LookupAddress": {
             "Type": "Task",
             "Resource":
               "arn:aws:lambda:us-east-1:123456789012:function:AddressFinder",
             "End": true
           }
         }
       },
       {
         "StartAt": "LookupPhone",
         "States": {
           "LookupPhone": {
             "Type": "Task",
             "Resource":
               "arn:aws:lambda:us-east-1:123456789012:function:PhoneFinder",
             "End": true
           }
         }
       }
      ]
    }
  }
}

AWS Step Function 对于并行任务使用 Type 为 Parallel 的状态来实现,使用 Branches 属性来定义多个分支,分支内允许多个状态执行,并且通过 End 标签来表示分支是否结束。AWS Step Function 使用一个大状态把分支涵盖在内,逻辑边界清晰。但其不支持并行任务之后再执行别的状态。 Spring Statemachine 例如定义如下状态机1,其演示并行任务处理并添加了错误处理以自动或手动修复任务问题,然后继续返回到可以再次运行任务的状态: 使用 spring-statemachine 可以将其状态定义如下:

@Override
public void configure(StateMachineStateConfigurer<States, Events> states)
    throws Exception {
  states
    .withStates()
      .initial(States.READY)
      .fork(States.FORK)
      .state(States.TASKS)
      .join(States.JOIN)
      .choice(States.CHOICE)
      .state(States.ERROR)
      .and()
      .withStates()
        .parent(States.TASKS)
        .initial(States.T1)
        .end(States.T1E)
        .and()
        // ... 篇幅有限
}

Spring Statemachine 中对于并行分支的执行则是通过 fork 和 join 两个状态来实现,fork 代表生成分支,join 代表合并分支。这种格式对比并行任务的优点在于既支持并行分支的嵌套,又支持了在所有并行分支完成后再进行下一步的功能。

初步方案

因此本次 PR 是主要是通过 Fork 和 Join 两种状态来实现状态机的并行能力,兼顾了上述两个相关工作的优点。其中,Fork代表并行分支的开始,Join代表并行分支的结束。 Fork 状态采用类似于 AWS Step Function 的设定,使用 Branches 来定义并行分支,但是不把子状态包含在内,而是写上分支的第一个元素即可。

"Fork": {
  "Type": "Fork",
  "Branches": [
    "SecondState",  // First state name in one branch
    "ThirdState"
  ],
  "Parallel": 0,  // limit on parallelism,0 stands for no limit
  "Timeout": 60000  // waiting time in milliseconds
},

最后所有并行分支都要指向 Join 状态来表示合并,而 Join 状态可以定义 Next 来确定下一步执行的状态。

Clone this wiki locally