

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

# HelloWorldWorkflowAsync アプリケーション
<a name="getting-started-example-helloworldworkflowasync"></a>

ワークフローは、アクティビティを使用せずに、一定のタスクをローカルで実行する方が望ましい場合があります。ただし、多くの場合、ワークフロータスクは、`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 基本的な概念: 分散実行](awsflow-basics-distributed-execution.md)」を参照してください。

このトピックは、HelloWorldWorkflowAsync のチュートリアルであり、アクティビティのいずれかを非同期メソッドに置き換える HelloWorldWorkflow の改訂版です。アプリケーションを実装するには、helloWorld.HelloWorldWorkflow パッケージのコピーをプロジェクトディレクトリに作成し、helloWorld.HelloWorldWorkflowAsync という名前を付けます。

**注記**  
このトピックは、「[HelloWorld アプリケーション](getting-started-example-helloworld.md)」および「[HelloWorldWorkflow アプリケーション](getting-started-example-helloworldworkflow.md)」トピックで説明している概念とファイルに基づき、作成されています。ファイルや概念に精通して先に進む前にこれらのトピックに表示されます。

以下のセクションでは、元の HelloWorldWorkflow コードを変更して非同期メソッドを使用する方法について説明します。

## HelloWorldWorkflowAsync アクティビティの実装
<a name="getting-started-example-helloworldworkflowasync.activities"></a>

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 ワークフローの実装
<a name="getting-started-example-helloworldworkflowasync.workflow"></a>

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`) が返ります。このオブジェクトは、オブジェクトの名前を表します。

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

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

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

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

この場合、アクティビティクライアントを呼び出して `getGreeting` アクティビティを実行せずに、あいさつで非同期の `getGreeting` メソッドを呼び出すという点が異なります。最終的な結果は同じですが、`getGreeting` メソッドの動作は、`getGreeting` アクティビティとは少し異なります。
+ ワークフローワーカーは、標準の関数呼び出しのセマンティクスを使用して `getGreeting` を実行します。ただし、アクティビティの非同期実行は Amazon SWF を介して行われます。
+ `getGreeting` は、ワークフロー実装のプロセスで実行されます。
+ `getGreeting` では、`String` オブジェクトではなく、`Promise<String>` オブジェクトが返ります。`Promise` で保持される文字列値を取得するには、その `get()` メソッドを呼び出します。ただし、アクティビティは非同期的に実行されているため、その戻り値はすぐには準備できない可能性があります。 `get()` は、非同期メソッドの戻り値が使用可能になるまで例外を発生させます。

  `Promise` の詳細な仕組みについては、「[AWS Flow Framework 基本的な概念: アクティビティとワークフロー間のデータ交換](awsflow-basics-data-exchange-activities-workflows.md)」を参照してください。

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

## HelloWorldWorkflowAsync のワークフローおよびアクティビティのホストおよびスターター
<a name="getting-started-example-helloworldworkflowasync.host"></a>

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` を実行します。