1
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 的错误情况下。

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

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

4

1 回答 1

2

是的。

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

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

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

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

Does the logger enforce logging only once per workflow run? Even if decisions are moved from one worker to another? Do you expect to see the log line appear in both worker's log? or is there magic behind the scene to prevent this from happening?

Each log line will only appear in the worker that actually executed the code as making decision -- in other words, in non-replay mode. That's the only magic :)

于 2021-12-10T02:52:41.583 回答