如何在前一个仍在执行时定期安排相同的 activity

How to periodically schedule a same activity when the previous one is still excuting

我的目标是让工作流定期(每 30 秒)向任务列表添加相同的 activity(只睡 1 分钟,什么都不做)。我还有多台机器托管 activity 工作人员同时轮询任务列表。当 activity 被调度时,其中一名工人可以轮询并执行。

我尝试使用 cron 装饰器创建 DynamicActivityClient 并使用 DynamicActivityClient.scheduleActivity() 定期安排 activity。但是,似乎要等到最后一个 activity 完成后才能安排 activity。在我的例子中,activity 每 1 分钟安排一次,而不是我在 cron 模式中设置的 30 秒。

包结构与aws sdk示例代码几乎相同:cron 是否有其他推荐的结构来实现这一目标?我对 SWF.Any 非常陌生,非常感谢您的建议。

cron 装饰器在内部依赖于 AsyncScheduledExecutor,它被设计为等待被调用方法中的所有异步代码完成,然后再次调用 cron。因此,您正在目睹的行为是意料之中的。解决方法是不从 cron 下的代码调用 activity,而是从不同范围内的代码调用。类似于:

// 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()

后立即

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

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