【问题标题】:How are Amazon SWF signals intended to be processed?打算如何处理 Amazon SWF 信号?
【发布时间】:2017-08-24 22:25:52
【问题描述】:

所以,我有一个场景,我定期调用 SignalWorkflowExecution() 传递工作流信号请求。在我编写的决策者中,我看到它在下一个轮询请求中接收到事件历史中的信号(以及在它之后开始的决策任务)。

我的问题是,如何防止再次处理该信号?也就是说,如果我得到了信号,然后提交一个新的活动进行工作,信号不会还在事件历史中吗?我看不到将信号与任何后续决策任务相关联的方法,并且不推荐在 Decider 中保持状态,因为这是 SWF 的意图。

Decider 是否还会轮询其他任务列表?也就是说,如果我的决策者接收到执行操作 A 的信号,然后它创建一个新决策以在任务列表 X 上安排活动 A(操作 A 的工作人员正在轮询),那么决策者是否也期望轮询任务列表 X 以查看是否已经为行动 A 安排了活动?否则,我看不到您如何避免每次收到新信号时一遍又一遍地处理信号,所有先前的信号都在历史记录中,那么我该如何避免重新处理它们呢?

我找不到很多关于使用信号的信息。我只看到一页,它没有解释如何在决策器中处理信号。

我只需要知道在工作流程中处理信号的“正确”方式。

【问题讨论】:

  • 您使用什么客户端框架和语言? AWS Flow Framework 为您处理所有这些复杂性。
  • 我正在使用 C# AWS 开发工具包。 SDK 不处理信号,您必须轮询它们,并自己在决策器中迭代事件的历史记录。 SWF 本身会在收到信号后自动生成一个决策任务,以便将决策任务发送给决策者,我不是你的意思,它会为你处理复杂性,因为我已经实现了一些东西,它只是循环永远获取信号并提交新的活动请求,而无法知道它已经处理了给定的信号。这就是文档所说的 - 自己处理历史以获得信号

标签: c# amazon amazon-swf


【解决方案1】:

当您调用PollForDecisionTask 时,响应中的参数之一是previousStartedEventId(已添加重点):

由决策者处理的此工作流执行的上一个决策任务的 DecisionTaskStarted 事件的 ID。 这可用于确定自决策者收到最后一个决策任务以来历史中的新事件

通常,每个决策任务都应处理自上一个决策任务以来的新事件。这不仅适用于信号 - 它适用于已完成的活动任务、子工作流、取消请求等。

【讨论】:

  • 啊啊啊。所以我应该只处理比收到的最后一个决策任务更新的信号。这似乎可行。谢谢。
  • 这有点晚了,但是如果您只打算查看最后几个事件(自上次决策任务以来),那么您应该确保以相反的顺序加载历史记录,直到您到达上一个StartedEventId。否则,对于包含许多事件的工作流,您最终可能不得不加载数千个历史事件,而不是仅加载(或多或少)新的事件。
【解决方案2】:

直接使用其 .NET SDK 对 Amazon SWF 进行编程非常困难且容易出错。如果你想坚持你的实施,那么 Kobi 的答案是正确的。

不过,您可能会发现 Guflow,一个用于编写 Amazon SWF 的开源 C#.NET 库,非常有用。我是这个库的作者。下面是一个示例,它显示了您可以轻松地暂停工作流程并发出信号:

[WorkflowDescription("1.0")]
public class OrderWorkflow : Workflow
{
    public OrderWorkflow()
    {
        ScheduleActivity<ReserveOrder>().OnFailure(PauseWhenItemIsNotAvailable);

        ScheduleActivity<ChargeCustomer>().AfterActivity<ReserveOrder>();

        ScheduleActivity<ShipOrder>().AfterActivity<ChargeCustomer>();
    }

    private WorkflowAction PauseWhenItemIsNotAvailable(ActivityFailedEvent e)
    {
        return e.Reason == "NotAvailable" ? Ignore : DefaultAction(e);
    }
    [WorkflowEvent(EventName.Signal)]
    public WorkflowAction SignalEvent(WorkflowSignaledEvent @event)
    {
        if (@event.SignalName == "ItemsArrived" && Activity<ReserveOrder>().LastFailedEvent()?.Reason=="NotAvailable")
            return Jump.ToActivity<ReserveOrder>();
        return Ignore;
    }
}

【讨论】:

    猜你喜欢
    • 2015-11-29
    • 2012-02-14
    • 1970-01-01
    • 2016-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多