HelloWorldWorkflowAsync アプリケーション - AWS Flow Framework for Java

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

HelloWorldWorkflowAsync アプリケーション

ワークフローは、アクティビティを使用せずに、一定のタスクをローカルで実行する方が望ましい場合があります。ただし、多くの場合、ワークフロータスクは、Promise<T> オブジェクトで表す値を処理する必要があります。Promise<T> オブジェクトを非同期ワークフローメソッドに渡すと、ただちに実行されますが、オブジェクトの準備が完了するまで Promise<T> オブジェクトの値にアクセスすることはできません。true を返すまでは Promise<T>.isReady をポーリングできますが、非効率なだけでなく、メソッドによって長時間ブロックされる場合があります。この場合は、非同期メソッドを使用する方が適切です。

非同期メソッドは、標準メソッドとよく似た方法で (多くの場合、ワークフロー実装クラスのメンバーとして) 実装され、ワークフロー実装のコンテキストで実行されます。非同期メソッドとして指定するには、@Asynchronous の注釈を適用します。これにより、アクティビティとよく似た方法で処理するようにフレームワークに指示されます。

  • ワークフロー実装で非同期メソッドが呼び出されると、ただちに返ります。非同期メソッドでは、通常 Promise<T> オブジェクトが返り、メソッドが完了すると準備状態になります。

  • 非同期メソッドを 1 つ以上の Promise<T> オブジェクトに渡すと、すべての入力オブジェクトが準備状態になるまで、実行は延期されます。そのため、非同期メソッドでは、例外のリスクなしに、入力値 Promise<T> にアクセスすることができます。

注記

AWS Flow Framework for 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 に設定されます。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 メソッドは以下とほとんど同じ方法で動作します。

  1. getName アクティビティを実行します。これにより、すぐに Promise<String> オブジェクト (name) が返ります。このオブジェクトは、オブジェクトの名前を表します。

  2. getGreeting 非同期メソッドを呼び出して、name オブジェクトを渡します。Promise<String> オブジェクト、greetinggetGreeting よりすぐに返ります。これは、あいさつを表します。

  3. say アクティビティを実行し、greeting オブジェクトに渡します。

  4. getName が完了すると、name は準備状態になり、getGreeting はその値を使用してあいさつを作成します。

  5. getGreeting が完了すると、greeting は準備状態になり、say によって文字列がコンソールに出力されます。

この場合、アクティビティクライアントを呼び出して getGreeting アクティビティを実行せずに、あいさつで非同期の getGreeting メソッドを呼び出すという点が異なります。最終的な結果は同じですが、getGreeting メソッドの動作は、getGreeting アクティビティとは少し異なります。

  • ワークフローワーカーは、標準の関数呼び出しのセマンティクスを使用して getGreeting を実行します。ただし、アクティビティの非同期実行は Amazon SWF を介して行われます。

  • getGreeting は、ワークフロー実装のプロセスで実行されます。

  • getGreeting では、String オブジェクトではなく、Promise<String> オブジェクトが返ります。Promise で保持される文字列値を取得するには、その get() メソッドを呼び出します。ただし、このアクティビティは非同期的に実行されているため、戻り値がすぐに準備状態にならない場合があります。get() は、非同期メソッドの戻り値が有効になるまで例外が発生します。

    Promise の詳細な仕組みについては、「AWS Flow Framework 基本概念: アクティビティとワークフロー間のデータ交換」を参照してください。

getGreeting では、あいさつの文字列を静的な Promise.asPromise メソッドに渡して戻り値を作成します。このメソッドでは、適切なタイプの Promise<T> オブジェクトを作成して値を設定し、準備状態に設定します。

HelloWorldWorkflowAsync のワークフローおよびアクティビティのホストおよびスターター

HelloWorldWorkflowAsync は、ワークフロー実装とアクティビティ実装のホストクラスとして GreeterWorker を実装します。このメソッドでは、taskListToPoll という名前を除き、HelloWorldWorkflow と同様に実装されます。名前は「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 と同様に実装されます。

ワークフローを実行するには、HelloWorldWorkflow の場合と同様に GreeterWorker および GreeterMain を実行します。