在过去的几年里,我在 Amazon SWF 上做了相当多的工作,但我仍然不清楚以下几点,而且我还无法在任何论坛上找到任何直接的答案。
我认为这些是非常基本的要求,当然其他人也可能遇到过。如果有人能澄清这些就太好了。
- 是否有一种简单的方法可以将工作流执行结果(可能只是简单的 bool 值)返回给工作流启动器?
- 有没有办法捕获 Activity 超时异常,以便我们可以在这种情况下运行自定义操作?
- 为什么 WorkflowExecutionHistory 不包含“事件”,而只包含“事件”?
- 为什么没有简单的方法可以从失败的地方重新启动工作流程?
我正在考虑在工作场所使用 SWF 进行更多业务流程,但这些限制/疑虑阻碍了我!
最终工作解决方案
public class ReturnResultActivityImpl implements ReturnResultActivity {
SettableFuture future;
public ReturnResultActivityImpl() {
}
public ReturnResultActivityImpl(SettableFuture future) {
this.future = future;
}
public void returnResult(WorkflowResult workflowResult) {
System.out.print("Marking future as Completed");
future.set(workflowResult);
}
}
public class WorkflowResult {
public WorkflowResult(boolean s, String n) {
this.success = s;
this.note = n;
}
private boolean success;
private String note;
}
public class WorkflowStarter {
@Autowired
ReturnResultActivityClient returnResultActivityClient;
@Autowired
DummyWorkflowClientExternalFactory dummyWorkflowClientExternalFactory;
@Autowired
AmazonSimpleWorkflowClient swfClient;
String domain = "test-domain;
boolean isRegister = true;
int days = 7;
int terminationTimeoutSeconds = 5000;
int threadPollCount = 2;
int taskExecutorThreadCount = 4;
public String testWorkflow() throws Exception {
SettableFuture<WorkflowResult> workflowResultFuture = SettableFuture.create();
String taskListName = "testTaskList-" + RandomStringUtils.randomAlphabetic(8);
ReturnResultActivity activity = new ReturnResultActivityImpl(workflowResultFuture);
SpringActivityWorker activityWorker = buildReturnResultActivityWorker(taskListName, Arrays.asList(activity));
DummyWorkflowClientExternalFactory factory = new DummyWorkflowClientExternalFactoryImpl(swfClient, domain);
factory.getClient().doSomething(taskListName)
WorkflowResult result = workflowResultSettableFuture.get(20, TimeUnit.SECONDS);
return "Call result note - " + result.getNote();
}
public SpringActivityWorker buildReturnResultActivityWorker(String taskListName, List activityImplementations)
throws Exception {
return setupActivityWorker(swfClient, domain, taskListName, isRegister, days, activityImplementations,
terminationTimeoutSeconds, threadPollCount, taskExecutorThreadCount);
}
}
public class Workflow {
@Autowired
private DummyActivityClient dummyActivityClient;
@Autowired
private ReturnResultActivityClient returnResultActivityClient;
@Override
public void doSomething(final String resultActivityTaskListName) {
Promise<Void> activityPromise = dummyActivityClient.dummyActivity();
returnResult(resultActivityTaskListName, activityPromise);
}
@Asynchronous
private void returnResult(final String taskListname, Promise waitFor) {
ActivitySchedulingOptions schedulingOptions = new ActivitySchedulingOptions();
schedulingOptions.setTaskList(taskListname);
WorkflowResult result = new WorkflowResult(true,"All successful");
returnResultActivityClient.returnResult(result, schedulingOptions);
}
}
最佳答案
标准模式是在工作流启动进程中托管一个特殊事件,用于交付结果。使用流程特定的任务列表以确保将其路由到启动器的正确实例。以下是实现步骤:
- 定义一个事件来接收结果。例如“returnResultActivity”。执行此事件以完成执行时传递给其构造函数的 Future。
- 工作流程启动时,它会接收“resultActivityTaskList”作为输入参数。最后,工作流使用工作流结果调用此事件。该事件被安排在已传递的任务列表上。
- 工作流启动器创建一个 ActivityWorker 和一个 Future 实例。然后它创建一个“returnResultActivity”的实例,并将该 future 作为构造函数参数。
- 然后,它向事件工作线程注册事件实例,并将其配置为轮询随机生成的任务列表名称。然后,它调用“启动工作流程执行”,并将生成的任务列表名称作为输入参数传递。
- 然后等待 Future 完成。 future.get() 将返回工作流程结果。
是的,如果您使用 AWS Flow Framework,则会在事件超时时引发超时异常。如果你不使用 Flow 框架,你的生活就会变得困难 100 倍。顺便说一句,工作流超时也会作为超时异常被抛出到父工作流中。不可能从超时实例本身捕获工作流超时异常。在这种情况下,建议不要依赖工作流超时,而只是创建一个计时器,该计时器将触发并通知工作流逻辑某些业务事件已超时。
因为单个事件执行有多个与其关联的事件。编写将历史记录转换为您喜欢的任何事件表示形式的代码应该很容易。此类代码将仅匹配与每个事件相关的事件。每个事件始终都有对相关事件的引用,因此很容易将它们汇总为更高级别的表示。
不幸的是,这个问题没有简单的答案。理想情况下,SWF 将通过将其历史记录复制到故障点来支持重新启动工作流程。但不支持。我个人认为,工作流应该以永不失败的方式编写,但总是在不失败的情况下处理失败。显然,如果由于意外情况而发生故障,它就不起作用了。在这种情况下,以可以从头开始重新启动的方式编写工作流程是最简单的方法。
关于amazon-swf - 亚马逊 SWF 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41596385/