HelloWorldWorkflowAsync 應用程式 - AWS Flow Framework 對於爪哇

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

HelloWorldWorkflowAsync 應用程式

在某些時候會偏好讓工作流程在本機執行某些任務,而不是使用活動。不過,工作流程任務通常包含處理 Promise<T> 物件所代表的值。如果您將 Promise<T> 物件傳遞給同步工作流程方法,則會立即執行方法,但無法存取 Promise<T> 物件值,直到物件就緒為止。您可以輪詢 Promise<T>.isReady,直到傳回 true 為止,但此效率較顯不彰,而且方法可能會被阻擋很長一段時間。較佳的方式是使用「非同步方法」

異步方法的實現非常類似於標準方法(通常作為工作流實現類的成員),並在工作流實現的上下文中運行。套用 @Asynchronous 註釋 (其指示框架將之視為活動),您即可將之指定為非同步方法。

  • 工作流程實作呼叫非同步方法時,會立即予以傳回。非同步方法一般會傳回 Promise<T> 物件,而此物件會在方法完成時就緒。

  • 如果您將一或多個 Promise<T> 物件傳遞給非同步方法,則會延遲執行,直到所有輸入物件都就緒為止。因此,非同步方法可以存取其輸入 Promise<T> 值,而不會發出例外狀況。

注意

由於AWS Flow Framework基於 Java 的非同步方法通常會執行多次,因此您應該僅將之用於快速且低成本的任務。您應該使用活動來執行大型運算這類冗長任務。如需詳細資訊,請參閱 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。在您向註冊活動界面之後,除非變更版本編號,否則無法進行修改。

其餘的活動方法實作與 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 方法的運作方式極為相同:

  1. 執行 getName 活動,其會立即傳回代表名稱的 Promise<String> 物件 name

  2. 呼叫 getGreeting 非同步方法,並將 name 物件遞給它。getGreeting 會立即傳回代表問候語的 Promise<String> 物件 greeting

  3. 執行 say 活動,並將 greeting 物件傳遞給它。

  4. getName 完成時,name 會就緒,且 getGreeting 會使用其值來建構問候語。

  5. getGreeting 完成時,greeting 會就緒,且 say 會將字串列印至主控台。

差異在於以問候語呼叫非同步 getGreeting 方法,而不是呼叫活動用戶端來執行 getGreeting 活動。最後的結果會相同,但 getGreeting 方法的運作方式與 getGreeting 活動有些不同。

  • 工作流程工作者會使用標準函數呼叫語意來執行 getGreeting。不過,會調解活動的非同步執 Amazon SWF。

  • getGreeting 會在工作流程實作程序中執行。

  • getGreeting 會傳回 Promise<String> 物件,而不是 String 物件。若要取得 Promise 保留的 String 值,您可以呼叫其 get() 方法。不過,因為活動正在透過非同步方式執行,所以其傳回值可能未能立即準備就緒;除非非同步方法的傳回值可用,否則 get() 將會引發例外狀況。

    如需 Promise 運作方式的詳細資訊,請參閱「AWS Flow Framework基本概念:活動與工作流程之間的資料交換」。

getGreeting 透過將問候語字串傳遞給靜態 Promise.asPromise 方法,來建立傳回值。此方法會建立適當類型的 Promise<T> 物件,並設定值,然後讓使之進入就緒狀態。

HelloWorldWorkflowAsync 工作流程和活動主機與啟動者

HelloWorldWorkflowAsync 將 GreeterWorker 實作為工作流程和活動實作的主機類別。此實作與 HelloWorldWorkflow 實作相同,差別在於 taskListToPoll 的名稱設為 "HelloWorldAsyncList"。

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 實作相同。

若要執行工作流程,請執行 GreeterWorkerGreeterMain,如同 HelloWorldWorkflow。