当前位置: 首页 > 知识库问答 >
问题:

在工作流代码中从 defer() 调用工作流活动是否安全?

松高歌
2023-03-14
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
  }
}
  

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

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

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

共有1个答案

秦光启
2023-03-14

是的。

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

>

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

    在粘性模式下,如果工作流未关闭,Cadence SDK将在某处阻塞;如果工作流实际上正在关闭,那么将执行延迟并收集决策。

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

    记录器是否仅在每次工作流运行时强制记录一次?即使决策从一个工人转移到另一个工人身上?您希望看到日志行出现在两个工人的日志中吗?还是幕后有魔法阻止这种事情发生?

    每个日志行将仅出现在实际执行代码作为决策的工作线程中 - 换句话说,在非重放模式下。这是唯一的神奇:)

  •  类似资料:
    • 我们希望异步调用一个长时间运行的活动,并且在一段时间后基于外部信号,想要取消该长时间运行的活动。 目前,活动了解取消的唯一方式是通过心跳。确保您的活动心跳,并且不吞下心跳方法抛出的异常。

    • 这可以被认为是在节奏工作流的循环中调用相同活动的后续问题:在活动迭代的情况下,工作流如何恢复?是继续调用第i个活动(跳过已经调用的活动)还是从0重新开始?如果是这样,如何编写工作流以跳过调用的活动(0-'k')?

    • 我在cadence workflow中有一个问题,我们可以在for循环中用不同的输入调用相同的活动吗?代码是确定性的吗?如果执行工作流的工作人员在执行过程中被停止并在稍后重新启动,cadence是否能够在重新构建工作流时重放事件。 例如,我有以下代码。 这里,第二个活动是在for循环中并行调用的。我的第一个问题是,这个代码是确定性的吗? 假设在循环5次迭代后,当i=5时,执行此工作流的工作程序终止

    • 一、功能说明 设置不同的工作流,每个子状态可以单独设置管理员,从而实现逐级专人审核制度 二、子功能导航 1.添加工作流 2.管理工作流 三、功能详解 1.添加工作流 1).如何进入本功能 导航栏 选择扩展 -> 菜单栏 选择工作流 -> 添加工作流 2).界面解释 点击后弹出如下界面 界面详述 1). 工作流名称: 您可以填入任意字符 2). 描述: 工作流简介 3). 审核级数: 可以设置次工作

    • 这是来自Fiddler(原始)捕获的代码的请求,由于某种原因没有授权参数:

    • temporal.io如何与cadenceworkflow.io?如果根据节奏工作流服务启动一个新项目,应该使用什么?