go - 如何创建自定义工作流定义?

标签 go cadence-workflow temporal-workflow

我们要求让我们的用户创建自己的工作流程。这些工作流可以有简单的是/否分支以及等待来自外部事件的信号。如果我们有完善的工作流定义,这就不是问题,但是由于工作流可以是动态的,这会带来一个更棘手的问题。

最佳答案

Temporal工作流是直接实现您的业务逻辑的代码。

对于无法在代码中硬编码业务逻辑的用例,应编写外部工作流定义语言的解释器。这种语言通常称为 DSL,因为它们在为特定领域实现时非常有用。 DSL 通常基于 YAML/Json/XML。有时它只是数据库表中的数据。

以下是我将如何构建工作流代码以支持自定义 DSL:

  1. 接收当前工作流定义 ID 和状态并返回要执行的操作列表的事件。此事件将当前状态(包括最近执行的操作的结果)应用到适当的 DSL 实例。结果是一组要执行的下一个操作。操作是特定于 DSL 的,但最常见的操作是执行事件、等待特定信号、休眠一段时间、完成或失败工作流
  2. 实现循环的工作流调用上述事件并执行请求的操作,直到请求工作流完成操作。

这是一个普通 DSL 的示例代码,它指定了要执行的一系列事件:

@ActivityInterface
public interface Interpreter {
  String getNextStep(String workflowType, String lastActivity);
}

public class SequenceInterpreter implements Interpreter {

  // dslWorkflowType->(activityType->nextActivity)
  private final Map<String, Map<String, String>> definitions;

  public SequenceInterpreter(Map<String, Map<String, String>> definitions) {
    this.definitions = definitions;
  }

  @Override
  public String getNextStep(String workflowType, String lastActivity) {
    Map<String, String> stateTransitions = definitions.get(workflowType);
    return stateTransitions.get(lastActivity);
  }
}

@WorkflowInterface    
public interface InterpreterWorkflow {
  @WorkflowMethod
  String execute(String type, String input);
  @QueryMethod
  String getCurrentActivity();
}

public class InterpreterWorkflowImpl implements InterpreterWorkflow {

  private final Interpreter interpreter = Workflow.newActivityStub(Interpreter.class);

  private final ActivityStub activities =
      Workflow.newUntypedActivityStub(
          new ActivityOptions.Builder().setScheduleToCloseTimeout(Duration.ofMinutes(10)).build());

  private String currentActivity = "init";
  private String lastActivityResult;

  @Override
  public String execute(String workflowType, String input) {
    do {
      currentActivity = interpreter.getNextStep(workflowType, currentActivity);
      lastActivityResult = activities.execute(currentActivity, String.class, lastActivityResult);
    } while (currentActivity != null);
    return lastActivityResult;
  }

  @Override
  public String getCurrentActivity() {
    return currentActivity;
  }
}

显然,现实生活中的解释器事件将接收一个更复杂的状态对象作为参数,并返回一个可能包含多种命令类型列表的结构。

关于go - 如何创建自定义工作流定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56583693/

相关文章:

cadence-workflow - Uber Cadence 中的子工作流程有什么好的用例?

go - 有没有一种方法可以将字段添加到将提供给工作流中所有事件的工作流上下文中?

go - Cadence 长时间运行的子工作流程

cadence-workflow - 时间工作流程与Cadence工作流程

go - 如何使用它的客户端查看 kubernetes 事件详细信息?

go - 锁定一个电话,直到其他电话结束

http - 如何在 go lang 的 Http Response 中打印一个 Struct

测试时Golang "plugin was built with a different version of package"