如何在前一个活动仍在激活时定期安排相同的活动

时间:2015-10-27 17:08:18

标签: amazon-web-services cron amazon-swf

我的目标是让一个工作流定期(每30秒)向taskList添加一个相同的活动(不做任何事情,只能睡1分钟)。此外,我有多台托管活动工作者的机器同时轮询taskList。当活动安排好后,其中一个工人可以轮询并执行。

我尝试使用cron装饰器创建DynamicActivityClient并使用DynamicActivityClient.scheduleActivity()定期安排活动。但是,似乎在最后一个活动完成之前不会安排活动。在我的情况下,活动每1分钟而不是30秒安排,我在cron模式中设置。

包结构与aws sdk示例代码几乎相同:cron 是否有任何其他结构建议实现这一目标?我对SWF很新。任何建议都非常感谢。

2 个答案:

答案 0 :(得分:0)

cron装饰器内部依赖于AsyncScheduledExecutor,它被设计为在调用cron之前等待调用方法中的所有异步代码完成。因此,您正在目睹的行为是可以预期的。解决方法是不从cron下的代码调用活动,而是从不同范围内的代码调用活动。类似的东西:

// This is a field
Settable<Void> invokeNextActivity = new Settable<>();

void executeCron() {
    scheduledExecutor.execute(new AsyncRunnable() {

        @Override
        public void run() throws Throwable {
            // Instead of executing activity here just unblock
            // its execution in a different scope.
            invokeNextActivity.set(null);
        }
    });
    // Recursive loop with each activity invocation 
    // gated on invokeNextActivity
    executeActivityLoop(invokeNextActivity);
}

@Asynchronous
void executeActivityLoop(Promise waitFor) {
   activityClient.executeMyActivityOnce();
   ivnokeNextActivity = new Settable<>();
   executeActivityLoop(ivnokeNextActivity);
}

我建议您阅读TryCatchFinally文档以了解错误处理和范围。

另一种选择是重写 AsyncScheduledExecutor 以调用 invoked.set(lastInvocationTime),而不是从 doFinally 调用调用 command.run()

答案 1 :(得分:0)

您可以通过编写更简单的工作流代码并使用工作流时钟和计时器来完成此操作。请参阅以下链接中的示例。 http://docs.aws.amazon.com/amazonswf/latest/awsflowguide/executioncontext.html

还要记住一件事。工作流程执行中允许的最大事件数为25000.因此,cron作业将永远不会运行,但您必须编写代码以在一段时间后开始新的工作流程执行。请参阅下面链接中提供的连续工作流程示例 http://docs.aws.amazon.com/amazonswf/latest/awsflowguide/continuous.html