【发布时间】:2019-01-12 16:06:13
【问题描述】:
我正在编写一个 AWS SWF 工作流程,其中第一个活动评估分区的数量并将其传递给子工作流程。决策者中的子工作流循环第一个活动返回的分区并启动最大值。允许并行活动。假设如果最大。允许的值为 50,一次并行启动 50 个活动。但是,我们面临的问题是直到所有 50 个完成后才开始下一个 50,即它停止所有其他分区直到所有 50 个完成。执行分 50 批执行。下面是代码示例:
@Override
public void execute(@Nonnull final Execution execution, @Nonnull final Step step)
throws ExecutionException {
Promise<Queue<Step>> stepQueuePromise = activitiesClient.partition(step, context);
Promise<Void> exitCode = executeSteps(stepQueuePromise, execution, context);
activitiesClient.verify(step, exitCode);
}
@Asynchronous
private Promise<Void> executeStepsInBatches(@Nonnull final Queue<Step> stepQueue,
@Wait final List<Promise<Void>> previousSteps,
@Nonnull final Execution execution,
@Nonnull final Context context) {
List<Promise<Void>> stepListPromises = new ArrayList<>();
for (int i = 0; i < concurrentStepThreshold && !stepQueue.isEmpty(); i++) {
Promise<Void> stepPromise = activitiesClient.execute(execution, stepQueue.poll(), context);
stepListPromises.add(stepPromise);
}
if (!stepListPromises.isEmpty()) {
return executeStepsInBatches(stepQueue, stepListPromises, execution, context);
} else {
return Promise.Void();
}
}
我们希望批量执行 50 个活动,但一旦少数活动完成,应提交新活动以匹配 50 个并行运行计数。有人可以建议我们如何实现这一目标吗?
编辑(新代码)
我试过下面的代码:
@Override
public void execute(@Nonnull final Execution execution, @Nonnull final Step step)
throws ExecutionException {
Promise<Queue<Step>> stepQueuePromise = activitiesClient.partition(step, context);
executeSteps(stepQueuePromise, execution, context);
}
@Asynchronous
private void executeSteps(@Nonnull final Promise<Queue<Step>> stepQueuePromise,
@Nonnull final Execution execution,
@Nonnull final Context context) {
Integer numNotReady = 0;
List<Promise<Void>> currentPromises = new ArrayList<>();
Iterator<Step> inputItr = stepQueuePromise.get().iterator();
while (inputItr.hasNext() && numNotReady < 20) {
Promise<Void> promise = activitiesClient.execute(execution, inputItr.next(), context);
currentPromises.add(promise);
if (!promise.isReady()) {
numNotReady++;
}
}
log.info("Num of not ready" + numNotReady);
waitForPromises(currentPromises);
}
@Asynchronous
void waitForPromises(@Wait final List<Promise<Void>> activityOutputs) {
}
第一个循环并行启动了 20 个活动。但是,即使决策者运行了新的活动,也没有提交。我可以看到我添加以验证决策程序运行的日志: 2018 年 8 月 6 日 17:16:34,962 [INFO] (SWF Decider ExecutorTaskList_1.0 1) com.amazon.traffic.cafe.orchestrator.swf.exec.impl.SwfExecutorImpl:未准备好的数量20 2018 年 8 月 6 日 17:16:50,808 [INFO] (SWF Decider ExecutorTaskList_1.0 1) com.amazon.traffic.cafe.orchestrator.swf.exec.impl.SwfExecutorImpl:
的数量【问题讨论】:
-
为什么要这样做?与一次安排所有活动任务相比,您希望获得什么好处?
-
我们不想全部运行一次,因为如果我们这样做,它会加载从加载活动调用的依赖服务。因此,我们希望将其限制为 50 作为并发运行。
-
你不能把所有这些都安排好,然后限制在 50 名工人的数量上吗?
-
我们对所有活动都有一个共同的活动类型。活动行为根据传递给它的参数而改变。我们不可能创建不同的活动工作者类型,因为我们有很多不同的配置可以传递给活动。因此,看看我们是否可以做这样的事情,我们只会走这条路。
-
您希望在所有工作流执行中一次只运行 50 个,还是每次工作流执行一次只运行 50 个?我认为是前者,因为您试图限制对下游系统的影响。对吗?
标签: amazon-swf