

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

# 在 Amazon SWF 中開發決策者
<a name="swf-dg-dev-deciders"></a>

決策者是在工作流程執行期間執行之工作流程類型的協調性邏輯實作。您可以為單一工作流程類型執行多個決策者。

由於工作流程執行的執行狀態會存放在其工作流程歷史記錄中，因此決策者可以是無狀態。Amazon SWF 會維護工作流程執行歷史記錄，並隨每個決策任務提供給決策者。這可讓您視需要動態新增和移除決策者，以高度擴展工作流程的處理。隨著系統負載的成長，您只要新增其他決策者即可處理增加的容量。不過，請注意，針對指定的工作流程執行，一次只會開啟一個決策任務。

每次工作流程執行發生狀態變更時，Amazon SWF 都會排程決策任務。每次決策者收到決策任務時，都會執行下列作業：
+ 解譯決策任務所提供的工作流程執行歷史記錄
+ 根據工作流程執行歷史記錄來套用協調性邏輯，並做出後續步驟的決策。每個決策都是以「決策」結構表示
+ 完成決策任務，並向 Amazon SWF 提供決策清單。

本節說明如何開發決策者，包含：
+ 以程式設計您的決策者輪詢決策任務
+ 以程式設計您的決策者解譯工作流程執行歷史記錄，並做出決策
+ 以程式設計您的決策者回應決策任務。

本節中的範例顯示如何以程式設計您的決策者進行電子商務範例工作流程。

您可以使用您喜歡的任何語言實作決策者，並在任何地方執行它，只要它可以透過其服務 API 與 Amazon SWF 通訊即可。

**Topics**
+ [定義協調性邏輯](#swf-dg-coordination-logic)
+ [輪詢決策任務](#swf-dg-polling-decision-tasks)
+ [套用協調性邏輯](#swf-dg-apply-coord-logic)
+ [回應決策](#swf-dg-responding-with-decisions)
+ [關閉工作流程執行](#swf-dg-closing-workflows)
+ [啟動決策者](#swf-dg-deciders-launch)

## 定義協調性邏輯
<a name="swf-dg-coordination-logic"></a>

開發決策者的第一件事是定義協調性邏輯。在電子商務範例中，於前一個活動完成之後排定每個活動的協調性邏輯可能會與下述類似：

```
IF lastEvent = "StartWorkflowInstance"
 addToDecisions ScheduleVerifyOrderActivity

ELSIF lastEvent = "CompleteVerifyOrderActivity"
 addToDecisions ScheduleChargeCreditCardActivity

ELSIF lastEvent = "CompleteChargeCreditCardActivity"
 addToDecisions ScheduleCompleteShipOrderActivity

ELSIF lastEvent = "CompleteShipOrderActivity"
 addToDecisions ScheduleRecordOrderCompletion

ELSIF lastEvent = "CompleteRecordOrderCompletion"
 addToDecisions CloseWorkflow

ENDIF
```

決策者會將協調性邏輯套用至工作流程執行歷史記錄，並在使用 `RespondDecisionTaskCompleted` 動作完成決策任務時建立決策清單。

## 輪詢決策任務
<a name="swf-dg-polling-decision-tasks"></a>

每個決策者都會輪詢決策任務。決策任務包含決策者用來產生決策的資訊 (例如，排定活動任務)。若要輪詢決策任務，決策者會使用 `PollForDecisionTask` 動作。

在此範例中，決策者會輪詢決策任務，並指定 `customerOrderWorkflow-0.1` 任務清單。

```
https://swf.us-east-1.amazonaws.com
PollForDecisionTask
{
  "domain": "867530901",
  "taskList": {"name": "customerOrderWorkflow-v0.1"},
  "identity": "Decider01",
  "maximumPageSize": 50,
  "reverseOrder": true
}
```

如果決策任務可從指定的任務清單中取得，Amazon SWF 會立即傳回它。如果沒有可用的決策任務，Amazon SWF 會保持連線開啟長達 60 秒，並在任務可用時立即傳回任務。如果沒有可用的任務，Amazon SWF 會傳回空的回應。空回應是 `taskToken` 值為空白字串的 `Task` 結構。確定以程式設計您的決策者要在收到空回應時輪詢另一個任務。

如果決策任務可用，Amazon SWF 會傳回包含決策任務的回應，以及工作流程執行歷史記錄的分頁檢視。

在此範例中，最新事件的類型指出已啟動的工作流程執行，而且輸入元素包含執行第一個任務所需的資訊。

```
{
  "events": [
    {
      "decisionTaskStartedEventAttributes": {
        "identity": "Decider01",
        "scheduledEventId": 2
      },
      "eventId": 3,
      "eventTimestamp": 1326593394.566,
      "eventType": "DecisionTaskStarted"
    }, {
      "decisionTaskScheduledEventAttributes": {
        "startToCloseTimeout": "600",
        "taskList": { "name": "specialTaskList" }
      },
      "eventId": 2,
      "eventTimestamp": 1326592619.474,
      "eventType": "DecisionTaskScheduled"
    }, {
      "eventId": 1,
      "eventTimestamp": 1326592619.474,
      "eventType": "WorkflowExecutionStarted",
      "workflowExecutionStartedEventAttributes": {
        "childPolicy" : "TERMINATE",
        "executionStartToCloseTimeout" : "3600",
        "input" : "data-used-decider-for-first-task",
        "parentInitiatedEventId": 0,
        "tagList" : ["music purchase", "digital", "ricoh-the-dog"],
        "taskList": { "name": "specialTaskList" },
        "taskStartToCloseTimeout": "600",
        "workflowType": {
          "name": "customerOrderWorkflow",
          "version": "1.0"
        }
      }
    }
  ],
  ...
}
```

收到工作流程執行歷史記錄之後，決策者會解譯歷史記錄，並根據協調性邏輯做出決策。

因為單一工作流程執行的工作流程歷史記錄事件數目可能很大，所以可能會將傳回的結果分割為數個頁面。若要擷取後續頁面，`PollForDecisionTask`請使用初始呼叫傳回的 *nextPageToken* 對 進行額外呼叫。請注意，您*不會*`GetWorkflowExecutionHistory`使用此 *nextPageToken* 呼叫 。相反地，請重新呼叫 `PollForDecisionTask`。

## 套用協調性邏輯
<a name="swf-dg-apply-coord-logic"></a>

決策者收到決策任務之後，請以程式設計您的決策者解譯工作流程執行歷史記錄，以判斷目前為止所發生的情況。據此，決策者應該會產生決策清單。

在電子商務範例中，我們只關心工作流程歷史記錄中的最後一個事件，因此邏輯定義如下。

```
IF lastEvent = "StartWorkflowInstance"
 addToDecisions ScheduleVerifyOrderActivity

ELSIF lastEvent = "CompleteVerifyOrderActivity"
 addToDecisions ScheduleChargeCreditCardActivity

ELSIF lastEvent = "CompleteChargeCreditCardActivity"
 addToDecisions ScheduleCompleteShipOrderActivity

ELSIF lastEvent = "CompleteShipOrderActivity"
 addToDecisions ScheduleRecordOrderCompletion

ELSIF lastEvent = "CompleteRecordOrderCompletion"
 addToDecisions CloseWorkflow

ENDIF
```

如果 lastEvent 是 `CompleteVerifyOrderActivity`，則 `ScheduleChargeCreditCardActivity` 活動將新增至決策清單。

在決策者決定要做出的決定後，可以使用適當的決策來回應 Amazon SWF (Amazon SWF)。

## 回應決策
<a name="swf-dg-responding-with-decisions"></a>

解譯工作流程歷史記錄並產生決策清單後，決策者已準備好以這些決策回應 Amazon SWF。

以程式設計您的決策者從工作流程執行歷史記錄擷取所需的資料，然後建立可指定工作流程之下一個適當動作的決策。決策者會使用 `RespondDecisionTaskCompleted`動作將這些決策傳輸回 Amazon SWF。如需可用[決策類型的](https://docs.aws.amazon.com/amazonswf/latest/apireference/API_Decision.html)清單，請參閱 *Amazon Simple Workflow Service API 參考*。

在電子商務範例中，決策者回應所產生的一組決策時，也會包含工作流程執行歷史記錄中的信用卡輸入。活動工作者接著會具有執行活動任務所需的資訊。

工作流程執行中的所有活動都完成時，決策者會關閉工作流程執行。

```
https://swf.us-east-1.amazonaws.com
RespondDecisionTaskCompleted
{
  "taskToken" : "12342e17-80f6-FAKE-TASK-TOKEN32f0223",
  "decisions" : [
    {
      "decisionType" :"ScheduleActivityTask",
      "scheduleActivityTaskDecisionAttributes" : {
        "control" :"OPTIONAL_DATA_FOR_DECIDER",
        "activityType" : {
          "name" :"ScheduleChargeCreditCardActivity",
          "version" :"1.1"
        },
        "activityId" :"3e2e6e55-e7c4-beef-feed-aa815722b7be",
        "scheduleToCloseTimeout" :"360",
        "taskList" : { "name" :"CC_TASKS" },
        "scheduleToStartTimeout" :"60",
        "startToCloseTimeout" :"300",
        "heartbeatTimeout" :"60",
        "input" : "4321-0001-0002-1234: 0212 : 234"
      }
    }
  ]
}
```

## 關閉工作流程執行
<a name="swf-dg-closing-workflows"></a>

決策者判斷商務流程完成 (亦即，沒有其他可執行的活動) 時，決策者會產生決策來關閉工作流程執行。

若要關閉工作流程執行，請以程式設計您的決策者解譯工作流程歷史記錄中的事件，以判斷目前為止執行中所發生的情況，並查看是否應該關閉工作流程執行。

如果工作流程已順利完成，則會使用 `CompleteWorkflowExecution` 決策呼叫 `RespondDecisionTaskCompleted` 來關閉工作流程執行。或者，您可以使用 `FailWorkflowExecution` 決策讓錯誤執行失敗。

在電子商務範例中，決策者會檢閱歷史記錄、根據協調性邏輯將關閉工作流程執行的決策新增至其決策清單，並使用關閉工作流程決策來啟動 `RespondDecisionTaskCompleted` 動作。

**注意**  
在一些情況下，關閉工作流程執行會失敗。例如，如果在決策者關閉工作流程執行時收到訊號，則關閉決策將會失敗。若要處理此可能性，請確定決策者繼續輪詢決策任務。此外，確保接收下一個決策任務的決策者回應 事件，在此情況下為 訊號，以防止執行關閉。

您也可能支援取消工作流程執行。這特別適用於長時間執行的工作流程。若要支援取消，您的決策者應該處理歷史記錄中的 `WorkflowExecutionCancelRequested` 事件。此事件指出已請求取消執行。您的決策者應該執行適當的清除動作，例如，取消進行中活動任務，以及關閉使用 `CancelWorkflowExecution` 決策呼叫 `RespondDecisionTaskCompleted` 動作的工作流程。

下列範例呼叫 `RespondDecisionTaskCompleted` 以指定取消目前工作流程執行。

```
https://swf.us-east-1.amazonaws.com
RespondDecisionTaskCompleted
{
  "taskToken" : "12342e17-80f6-FAKE-TASK-TOKEN32f0223",
  "decisions" : [
    {
      "decisionType":"CancelWorkflowExecution",
      "CancelWorkflowExecutionAttributes":{
        "Details": "Customer canceled order"
      }
    }
  ]
}
```

Amazon SWF 會檢查以確保關閉或取消工作流程執行的決定是決策者傳送的最後一個決策。亦即，一組決策不允許在關閉工作流程的決策後面還有決策。

## 啟動決策者
<a name="swf-dg-deciders-launch"></a>

完成決策者開發之後，您即可準備啟動一或多個決策者。

若要啟動決策者，請將協調性邏輯封裝至可用於決策者平台的執行檔。例如，您可以將決策者程式碼封裝為可在 Linux 和 Windows 電腦上執行的 Java 執行檔。

啟動後，您的決策者應該開始輪詢 Amazon SWF 任務。在您開始工作流程執行和 Amazon SWF 排程決策任務之前，這些輪詢將會逾時並取得空的回應。空回應是 `taskToken` 值為空白字串的 `Task` 結構。決策者只應該繼續輪詢。

Amazon SWF 可確保隨時只有一個決策任務可用於工作流程執行。這能防止決策發生衝突的問題。此外，Amazon SWF 可確保將單一決策任務指派給單一決策者，無論執行的決策者數目為何。

如果發生決策者正在處理另一個決策任務時產生決策任務的情況，Amazon SWF 會將新任務排入佇列，直到目前的任務完成為止。目前任務完成後，Amazon SWF 就會提供新的決策任務。此外，決策任務的批次處理概念是，如果在決策者處理決策任務時完成多個活動，Amazon SWF 只會建立單一新決策任務，以考慮完成多個任務。不過，每個任務完成都會在工作流程執行歷史記錄中收到個別事件。

由於輪詢是傳出請求，決策者可以在可存取 Amazon SWF 端點的任何網路上執行 。

若要工作流程執行有所進展，必須執行一或多個決策者。您可以視需要啟動任意數量的決策者。Amazon SWF 支援在同一任務清單上輪詢多個決策者。