【问题标题】:possible bug in FlowFlow 中可能存在的错误
【发布时间】:2016-07-30 18:38:33
【问题描述】:

可能的错误:

当子 B 失败时,GenericWorkflowClientImpl 中的 handleStartChildWorkflowExecutionFailed 方法根据工作流 id 作为键从 scheduleExternalWorkflows 映射中删除了“OpenRequestInfo”。由于 5 个子工作流具有相同的工作流 ID。因此,一旦子 B 初始化失败,地图就会变为空。因此,父工作流无法完成,因为 4 个子工作流请求永远无法在 handle* 方法中正确关闭。

第 335 行显示 handleStartChildWorkflowExecutionFailed 删除失败的条目。

https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-swf-libraries/src/main/java/com/amazonaws/services/simpleworkflow/flow/worker/GenericWorkflowClientImpl.java#L335

【问题讨论】:

  • 你看过卡住工作流的异步堆栈跟踪吗?它是使用 WorkflowReplayer.getAsynchronousThreadDumpAsString() 发出的。

标签: amazon-web-services workflow aws-sdk amazon-swf


【解决方案1】:
@Override
protected ExternalTaskCancellationHandler doExecute(final     ExternalTaskCompletionHandle handle) throws Throwable {
    context.setCompletionHandle(handle);
    String workflowId = attributes.getWorkflowId();
    if (scheduledExternalWorkflows.containsKey(workflowId)) {
        WorkflowExecution workflowExecution = new WorkflowExecution();
        workflowExecution.setWorkflowId(workflowId);
        WorkflowType workflowType = attributes.getWorkflowType();

        long fakeEventId = -1;
        handle.fail(new StartChildWorkflowFailedException(fakeEventId, workflowExecution, workflowType,       StartChildWorkflowExecutionFailedCause.WORKFLOW_ALREADY_RUNNING.toString())    );

        return new ChildWorkflowCancellationHandler(workflowId, handle);
    }
        decisions.startChildWorkflowExecution(attributes);
        scheduledExternalWorkflows.put(workflowId, context);
        return new ChildWorkflowCancellationHandler(workflowId, handle);
    }
}

}

更新了这个类的第 162 行:

https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-swf-libraries/src/main/java/com/amazonaws/services/simpleworkflow/flow/worker/GenericWorkflowClientImpl.java#L163

【讨论】:

    【解决方案2】:

    Update2:问题仍未解决 :(.

    更新:可能是提交 0a183e02b29b06e9324b740af40daff9193c9290 修复了该错误。请验证。

    这看起来像是DecisionsHelper 中的一个错误。它假定 DecisionId 永远不会被重用,因为它永远不会从 decisions 映射中删除。 DecisionId 永远不会重用于活动和 lambda,但正如您发现的那样,子工作流并不总是如此:(。解决方法是不重用子工作流 id。

    在您的情况下,我看不到尝试安排与父工作流具有相同 ID 的子工作流的原因,因为它具有有关子工作流状态的完整信息,并且可以轻松避免它。顺便说一句,您是否考虑过在 CronWithRety 示例中将 CronInvocationSchedule 与 AsyncScheduledExecutor 一起使用?

    但是,当父工作流的多个实例可以创建具有相同 id 的子工作流时,这个错误是很糟糕的。

    【讨论】:

    • 是的,我了解触发 continue as new 的条件。我的猜测是还有一些异步调用仍在运行,所以它们没有完成。但是,我还检查了工作流历史事件。似乎所有子工作流程都已完成,这与线程转储显示的不同。请参阅答案部分中的工作流程历史审核。
    • 感谢您的指出!我已经调试了几个场景。只有当同一个父级一遍又一遍地启动同一个子级时,才会发生这种情况,这会导致子级工作流初始化失败并挂起父级工作流。我在主要问题部分更新了我的调试结果。
    • 不幸的是,我们的用例是固定的,所以我必须一直使用那个子工作流 ID。您能否就如何修复此错误提供一些建议?
    • 在上一个工作流完成之前不要尝试启动子工作流。这很容易,因为您可以将 Promise 从上一个子工作流开始链接到下一个子工作流调用。
    • 我已经检查了这个提交,它没有解决问题。由于 ChildStateMachine.java 类中缺少状态,我仍然得到父工作流失败。我已通过提供缺失的状态并在本地重建 jar 来解决此问题
    猜你喜欢
    • 2019-04-18
    • 2013-10-11
    • 2019-12-22
    • 2012-01-21
    • 2018-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多