

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

# 執行內容
<a name="executioncontext"></a>

**Topics**
+ [決策內容](#executioncontext.decision)
+ [活動執行內容](#activitycontext)

此框架提供工作流程和活動實作的環境內容。此內容專門用於處理中的任務，並提供可在實作中使用的一些公用程式。每次工作者處理新任務時，都會建立內容物件。

## 決策內容
<a name="executioncontext.decision"></a>

執行決策任務時，框架會透過 `DecisionContext` 類別提供工作流程實作的內容。 `DecisionContext` 提供工作流程執行之執行 ID，以及時鐘與計時器功能等這類上下文相關資訊。.

### 存取工作流程實作中的 DecisionContext
<a name="executioncontext.decision.access"></a>

您可以使用 `DecisionContextProviderImpl` 類別存取工作流程實作中的 `DecisionContext`。或者，您可以使用 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 用戶端物件可以透過在 上呼叫 `getService`方法來擷取`ActivityExecutionContext`。如果您想要直接呼叫 Amazon SWF 服務，這會很有用。