【问题标题】:What is the best way/pattern to process a signal in Cadence/Temporal workflow在节奏/时间工作流程中处理信号的最佳方式/模式是什么
【发布时间】:2022-06-17 12:11:04
【问题描述】:

我可以通过不同的方式实现信号方法(处理程序)。但是,我有时会遇到以下问题:

  1. 我要保证 FIFO 处理
  2. 我想处理过早调用信号方法的 signalWithStart 的“比赛条件”
  3. 我希望安全地重置工作流程。重置后,信号可以在历史早期重新应用
  4. 我想确保工作流不会在处理信号之前提前完成

【问题讨论】:

    标签: cadence-workflow temporal-workflow uber-cadence


    【解决方案1】:
    1. 保证 FIFO 处理
    2. 处理过早调用信号方法的 signalWithStart 的“比赛条件”
    3. 可以安全地重置工作流程。重置后,信号可以在历史早期重新应用
    4. 确保工作流不会在处理信号之前提前完成

    这些是在 Cadence/Temporal 工作流程中使用信号时最常见的错误。

    您可以应用一种设计模式来共同解决所有问题。

    这个想法是简化信号处理程序以始终将信号放入队列中,并且工作流方法将启动另一个工作流线程来处理队列。

    它基于样本 (Cadence& Temporal)

    Java

    public class MyWorkflow{
       private Queue<SignalRequest> signalRequestQueue = new LinkedList<>(); 
    
       public void mySignalMethod(SignalRequest req){
           signalRequestQueue.add(req);
       }
    
       public Output myWorkflwMethod(Input input){
          //1. do everything necessary/needed before actually processing a signal
          ...
    
          //2. spin up a workflow thread to process 
          Async.procedure(
          () -> {
              while (true) {
                  Workflow.await(() -> !signalRequestQueue.isEmpty());
                  final SignalRequest request = signalRequestQueue.poll();
                  processSignal(request);
              }
          });
    
    
          //3. always wait for queue to be empty before completing the workflow(return)
          Workflow.await(() -> signalRequestQueue.isEmpty());
          return output
       }
    
       private void processSignal(request){
         // do your actual processing here. 
         // If a process a single signal may take too much time and you don't care about FIFO, you could also start another workflow thread to process signals in parallel.
         ...
       }
    }
    

    Golang 等其他语言呢

    Golang SDK 没有 1/2/3 的相同问题。这是 Golang SDK 提供了一个完全不同的 API 来处理信号。

    Golang SDK 不需要将信号方法定义为处理程序,而是需要工作流侦听通道来处理信号,这正是这个答案所建议的。查看信号 API 的示例。

    查看示例(Cadence / Temporal

    唯一的问题是 4 - 确保工作流程不会在处理信号之前提前完成。这是 Golang SDK 的常见错误。建议是在完成或 continueAsNew 工作流之前始终排空信号通道。 See this sample of how to drain signal channel in Golang.

    【讨论】: