本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
HelloWorldWorkflowAsync应用程序
有时,最好让工作流程在本地执行某些任务,而不是使用活动。不过,工作流程任务通常涉及处理 Promise<T>
对象表示的值。如果将 Promise<T>
对象传递给一个同步工作流程方法,该方法将立即执行,但无法访问 Promise<T>
对象的值,直到该对象准备就绪。您可以轮询 Promise<T>.isReady
,直到它返回 true
,但这样做的效率非常低,并且该方法可能会阻止很长时间。更好的方法是使用异步方法。
异步方法的实现与标准方法类似,通常是作为工作流实现类的成员,并在工作流实现的上下文中运行。您可以应用 @Asynchronous
注释将其指定为异步方法,这会指示框架像对待活动一样处理它。
-
在工作流程实现调用异步方法时,它将立即返回。异步方法通常返回一个
Promise<T>
对象,在该方法完成时,该对象将变为就绪状态。 -
如果为异步方法传递一个或多个
Promise<T>
对象,它将推迟执行,直到所有输入对象准备就绪。因此,异步方法可以访问其输入Promise<T>
值,而不会出现引发异常的风险。
注意
由于 for Java 执行工作流程的方式,异步方法通常会执行多次,因此只能将它们用于快速的低开销任务。 AWS Flow Framework 您应该使用活动执行时间较长的任务,如规模较大的计算。有关更多信息,请参阅 AWS Flow Framework 基本概念:分布式执行。
本主题是的演练 HelloWorldWorkflowAsync,它是一个修改后的版本 HelloWorldWorkflow ,它用异步方法替换了其中一个活动。要实现该应用程序,请创建 HelloWorld 的副本。 HelloWorldWorkflow 打包到你的项目目录中然后把它命名为 HelloWorld。 HelloWorldWorkflowAsync。
注意
本主题以 HelloWorld 应用程序和 HelloWorldWorkflow 应用程序主题中提供的概念和文件为基础。熟悉这些文件和中介绍的概念,这些主题,然后再继续。
以下各节介绍如何修改原始 HelloWorldWorkflow 代码以使用异步方法。
HelloWorldWorkflowAsync 活动实施
HelloWorldWorkflowAsync 在中实现其活动工作者接口GreeterActivities
,如下所示:
import com.amazonaws.services.simpleworkflow.flow.annotations.Activities; import com.amazonaws.services.simpleworkflow.flow.annotations.ActivityRegistrationOptions; @Activities(version="2.0") @ActivityRegistrationOptions(defaultTaskScheduleToStartTimeoutSeconds = 300, defaultTaskStartToCloseTimeoutSeconds = 10) public interface GreeterActivities { public String getName(); public void say(String what); }
此接口与使用的接口类似 HelloWorldWorkflow,但有以下例外:
-
它忽略
getGreeting
活动;该任务现在由异步方法进行处理。 -
版本号设置为 2.0。在 Amazon SWF 注册活动接口后,您无法对其进行修改,除非更改版本号。
其余的活动方法实现与相同 HelloWorldWorkflow。只需从 GreeterActivitiesImpl
中删除 getGreeting
。
HelloWorldWorkflowAsync 工作流程实施
HelloWorldWorkflowAsync 定义工作流界面如下:
import com.amazonaws.services.simpleworkflow.flow.annotations.Execute; import com.amazonaws.services.simpleworkflow.flow.annotations.Workflow; import com.amazonaws.services.simpleworkflow.flow.annotations.WorkflowRegistrationOptions; @Workflow @WorkflowRegistrationOptions(defaultExecutionStartToCloseTimeoutSeconds = 3600) public interface GreeterWorkflow { @Execute(version = "2.0") public void greet(); }
HelloWorldWorkflow 除了新的版本号外,该接口与相同。与活动一样,如果要更改注册的工作流程,您必须更改其版本。
HelloWorldWorkflowAsync 按如下方式实现工作流程:
import com.amazonaws.services.simpleworkflow.flow.annotations.Asynchronous; import com.amazonaws.services.simpleworkflow.flow.core.Promise; public class GreeterWorkflowImpl implements GreeterWorkflow { private GreeterActivitiesClient operations = new GreeterActivitiesClientImpl(); @Override public void greet() { Promise<String> name = operations.getName(); Promise<String> greeting = getGreeting(name); operations.say(greeting); } @Asynchronous private Promise<String> getGreeting(Promise<String> name) { String returnString = "Hello " + name.get() + "!"; return Promise.asPromise(returnString); } }
HelloWorldWorkflowAsync 用getGreeting
异步方法替换getGreeting
活动,但该greet
方法的工作方式大致相同:
-
执行
getName
活动,这会立即返回Promise<String>
对象name
,它表示名称。 -
调用
getGreeting
异步方法并为其传递name
对象。getGreeting
立即返回Promise<String>
对象greeting
,它表示问候语。 -
执行
say
活动并为其传递greeting
对象。 -
在
getName
完成时,name
会变为就绪状态,getGreeting
将使用它的值构建问候语。 -
在
getGreeting
完成时,greeting
会变为就绪状态,say
会将字符串输出到控制台。
不同之处在于,greet 调用异步 getGreeting
方法,而不是调用活动客户端来执行 getGreeting
活动。实际结果是相同的,但 getGreeting
方法的工作方式与 getGreeting
活动略有不同。
-
工作流程工作线程使用标准函数调用语义来执行
getGreeting
。不过,活动异步执行是由 Amazon SWF 协调的。 -
getGreeting
在工作流程实现的进程中运行。 -
getGreeting
返回一个Promise<String>
对象,而不是String
对象。要获取Promise
保留的字符串值,您需要调用其get()
方法。但是,由于活动是异步运行的,因此其返回值可能无法立即准备就绪;在异步方法的返回值可用之前,get()
将引发异常。有关
Promise
如何工作的更多信息,请参阅 AWS Flow Framework 基本概念:活动和工作流之间的数据交换。
getGreeting
将问候语字符串传递给静态 Promise.asPromise
方法以创建返回值。该方法创建一个具有相应类型的 Promise<T>
对象,设置对象值,然后将其置于就绪状态。
HelloWorldWorkflowAsync工作流程和活动主持人和入门者
HelloWorldWorkflowAsync 实现GreeterWorker
为工作流程和活动实现的主机类。除了taskListToPoll
名称设置为 “HelloWorldAsyncList
” 之外,它与 HelloWorldWorkflow实现相同。
import com.amazonaws.ClientConfiguration; import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow; import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClient; import com.amazonaws.services.simpleworkflow.flow.ActivityWorker; import com.amazonaws.services.simpleworkflow.flow.WorkflowWorker; public class GreeterWorker { public static void main(String[] args) throws Exception { ClientConfiguration config = new ClientConfiguration().withSocketTimeout(70*1000); String swfAccessId = System.getenv("AWS_ACCESS_KEY_ID"); String swfSecretKey = System.getenv("AWS_SECRET_KEY"); AWSCredentials awsCredentials = new BasicAWSCredentials(swfAccessId, swfSecretKey); AmazonSimpleWorkflow service = new AmazonSimpleWorkflowClient(awsCredentials, config); service.setEndpoint("https://swf.us-east-1.amazonaws.com"); String domain = "helloWorldWalkthrough"; String taskListToPoll = "HelloWorldAsyncList"; ActivityWorker aw = new ActivityWorker(service, domain, taskListToPoll); aw.addActivitiesImplementation(new GreeterActivitiesImpl()); aw.start(); WorkflowWorker wfw = new WorkflowWorker(service, domain, taskListToPoll); wfw.addWorkflowImplementationType(GreeterWorkflowImpl.class); wfw.start(); } }
HelloWorldWorkflowAsync 在中实现工作流程启动器GreeterMain
;它与 HelloWorldWorkflow 实现相同。
要执行工作流程,请运行GreeterWorker
和GreeterMain
,就像运行一样 HelloWorldWorkflow。