

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

# 実行コンテキスト
<a name="executioncontext"></a>

**Topics**
+ [決定コンテキスト](#executioncontext.decision)
+ [アクティビティ実行コンテキスト](#activitycontext)

フレームワークは、環境コンテキストをワークフローおよびアクティビティの実装に渡します。このコンテキストは、処理されているタスク固有であり、実装で使用できるいくつかのユーティリティが用意されています。コンテキストオブジェクトは、新しいタスクがワーカーに処理される度に作成されます。

## 決定コンテキスト
<a name="executioncontext.decision"></a>

決定タスクが実行されると、フレームワークは `DecisionContext` クラスを介してワークフロー実装にコンテキストを提供します。`DecisionContext` は、ワークフロー実行 ID、クロック、タイマー機能など、状況に応じた情報を提供します。

### ワークフロー実装の DecisionContext にアクセスする
<a name="executioncontext.decision.access"></a>

ワークフロー実装の `DecisionContext` にアクセスするには、`DecisionContextProviderImpl` クラスを使用します。または、テスト容易性と依存関係に示す Spring を使用して、フィールドのコンテキスト、またはワークフロー実装のプロパティを挿入することもできます。

```
DecisionContextProvider contextProvider
    = new DecisionContextProviderImpl();
DecisionContext context = contextProvider.getDecisionContext();
```

### クロックおよびタイマーの作成
<a name="executioncontext.decision.timer"></a>

`DecisionContext` には、タイマーおよびクロック機能を提供する `WorkflowClock` タイプのプロパティが含まれます。ワークフローロジックは決定的である必要があるため、ワークフロー実装でシステムクロックを直接使用しないでください。`WorkflowClock` の `currentTimeMills` メソッドは、処理されているディシジョンの開始イベントの時間を返します。これにより、再生時に同じ時間の値を取得できるため、ワークフローロジックを決定的にすることができます。

`WorkflowClock` にも `createTimer` メソッドがあります。このメソッドでは、指定された間隔が過ぎると、準備完了状態になる `Promise` オブジェクトが返ります。この値を他の非同期メソッドのパラメータとして使用し、指定の時間まで実行を遅らせることができます。このように、非同期メソッドまたはアクティビティを効率的にスケジュールして、後で実行することができます。

次の例では、アクティビティを定期的に呼び出す方法について説明します。

```
@Workflow
@WorkflowRegistrationOptions(defaultExecutionStartToCloseTimeoutSeconds = 60,
               defaultTaskStartToCloseTimeoutSeconds = 10)
public interface PeriodicWorkflow {

    @Execute(version = "1.0")
    void periodicWorkflow();
}

@Activities(version = "1.0")
@ActivityRegistrationOptions(defaultTaskScheduleToStartTimeoutSeconds = 300,
                             defaultTaskStartToCloseTimeoutSeconds = 3600)
public interface PeriodicActivity {
    void activity1();
}

public class PeriodicWorkflowImpl implements PeriodicWorkflow {

    private DecisionContextProvider contextProvider
         = new DecisionContextProviderImpl();

    private WorkflowClock clock
         = contextProvider.getDecisionContext().getWorkflowClock();

    @Override
    public void periodicWorkflow() {
        callPeriodicActivity(0);
    }

    @Asynchronous
    private void callPeriodicActivity(int count,
                                      Promise<?>... waitFor) {
        if (count == 100) {
            return;
        }
        PeriodicActivityClient client = new PeriodicActivityClientImpl();
        // call activity
        Promise<Void> activityCompletion = client.activity1();

        Promise<Void> timer = clock.createTimer(3600);

        // Repeat the activity either after 1 hour or after previous activity run
        // if it takes longer than 1 hour
        callPeriodicActivity(count + 1, timer, activityCompletion);
    }
}


public class PeriodicActivityImpl implements PeriodicActivity
{
@Override
   public void activity1() {
      ...
      }
}
```

上記の例では、`callPeriodicActivity` 非同期メソッドは `activity1` を呼び出した後、現在の `AsyncDecisionContext` を使用してタイマーを作成します。これにより、返った `Promise` を引数として、それ自体に再帰的な呼び出しを行います。この再帰的呼び出しは、実行前にタイマーが鳴るまで (この例では 1 時間) 待機します。

## アクティビティ実行コンテキスト
<a name="activitycontext"></a>

ディシジョンタスクが処理されると `DecisionContext` でコンテキストが渡されるように、`ActivityExecutionContext` では、アクティビティタスクが処理されると同様のコンテキスト情報が渡されます。このコンテキストでは、`ActivityExecutionContextProviderImpl` クラスを介して、アクティビティコードを利用できます。

```
ActivityExecutionContextProvider provider
    = new ActivityExecutionContextProviderImpl();
ActivityExecutionContext aec = provider.getActivityExecutionContext();
```

以下のアクションは、`ActivityExecutionContext` を使用して実行できます。

### 長時間実行アクティビティのハートビート
<a name="activitycontext.heartbeat"></a>

アクティビティが長時間実行されている場合は、その進行状況を定期的に Amazon SWF に報告し、タスクが進行中であることを知らせます。このようなハートビートが不明な場合に、タスクのハートビートのタイムアウトが、アクティビティタイプの登録時、またはアクティビティのスケジュール時に設定されていると、タイムアウトが発生する場合があります。ハートビートを送信するには、`ActivityExecutionContext` の `recordActivityHeartbeat` メソッドを使用できます。また、ハートビートには、実行中のアクティビティをキャンセルするメカニズムがあります。詳細と例については、「[エラー処理](errorhandling.md)」セクションを参照してください。

### アクティビティタスクの詳細を取得する
<a name="activitycontext.details"></a>

必要に応じて、エグゼキューターがタスクを取得した際に Amazon SWF によって渡されたアクティビティタスクの詳細をすべて取得することができます。この詳細には、タスク、タスクタイプ、タスクトークンなどの入力に関する情報が含まれます。手動で行われているアクティビティ (例: 人間によるアクション) を実装する場合は、`ActivityExecutionContext` を使用して、タスクトークンを取得し、アクティビティタスクを少しずつ完了するプロセスに渡す必要があります。詳細については、「[マニュアルでのアクティビティの完了](activityimpl.md#activityimpl.complete)」セクションを参照してください。

### エグゼキューターによって使用されている Amazon SWF クライアントオブジェクトを取得する
<a name="activitycontext.client"></a>

エグゼキューターによって使用されている Amazon SWF クライアントオブジェクトは、`ActivityExecutionContext` の `getService` メソッドを呼び出して取得できます。このメソッドは、Amazon SWF サービスを直接呼び出す場合に便利です。