【问题标题】:Is it safe to invoke a workflow activity from defer() within the workflow code?从工作流代码中的 defer() 调用工作流活动是否安全?
【发布时间】:2022-01-14 15:58:15
【问题描述】:
func MyWorkflow(ctx Context) (retErr error) { 
  log := workflow.GetLogger()
  log.Info("starting my workflow")
  defer func() {
    if retErr != nil {
      DoActivityCleanupError(ctx, ..)
    } else {
      DoActivityCleanupNoError(ctx, ...)
    }
  }
  err := DoActivityA(ctx, ...)
  if err != nil {
    return err
  }
  ...
  err := DoActivityB(ctx, ...)
  if err != nil {
    return err
  }
}
  

基本上,我们希望在工作流退出时执行所有活动,ActivityCleanupNoError 和 ActivityCleanupError(尤其是在我们不想在所有错误返回中重复调用 ActivityCleanupError 的错误情况下。

这适用于分布式决策吗?例如,如果工作流决策的所有权从一个工作人员转移到另一个工作人员,是否会触发原始工作人员的延迟?

额外问题:记录器是否在每次工作流运行时只强制记录一次?即使决策从一名工人转移到另一名工人?您是否希望看到日志行出现在两个工作人员的日志中?还是幕后有什么魔法可以防止这种情况发生?

【问题讨论】:

    标签: cadence-workflow temporal-workflow


    【解决方案1】:

    是的。

    但是要理解为什么它是安全的却相当复杂。这是如何得出结论的:

    1. 在无粘性模式(无粘性缓存)下,Cadence SDK 将始终执行工作流代码以做出(收集)工作流决策,并释放所有 goroutines/stack。释放它们时,将执行延迟,这意味着清理活动代码路径将运行 - 但是,这些决定将被忽略。因此它不会影响实际的正确性。

    2. 在粘滞模式下,如果工作流没有关闭,Cadence SDK 会在某处阻塞;如果工作流实际上正在关闭,则将执行延迟并收集决策。

    3. 当粘性缓存(goroutines/stack)被驱逐时,会发生什么和1完全一样,所以也是安全的。

    记录器是否在每次工作流运行时只强制记录一次?即使决策从一名工人转移到另一名工人?您是否希望看到日志行出现在两个工作人员的日志中?还是幕后有什么魔法可以防止这种情况发生?

    每个日志行只会出现在实际执行代码作为决策的工作人员中——换句话说,在非重放模式下。这是唯一的魔法:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多