

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

# 訂閱工作流程教學第 4 部分：實作活動任務輪詢器
<a name="swf-sns-tutorial-implementing-activities-poller"></a>

在 Amazon SWF 中，執行中工作流程執行的活動任務會出現在*活動任務清單中*，該任務會在您排程工作流程中的活動時提供。

我們將實作基本活動輪詢器來處理工作流程的這些任務，並在 Amazon SWF 在活動任務清單上放置任務以啟動活動時，使用它來啟動我們的活動。

若要開始，請建立稱為 `swf_sns_activities.rb` 的新檔案。我們將會用來：
+ 實例化我們已建立的活動類別。
+ 向 Amazon SWF 註冊每個活動。
+ 會輪詢活動，並在每個活動的名稱出現在活動任務清單時呼叫每個活動的 `do_activity`。

在 `swf_sns_activities.rb` 中，新增下列陳述式以要求我們定義的每個活動類別。

```
require_relative 'get_contact_activity.rb'
require_relative 'subscribe_topic_activity.rb'
require_relative 'wait_for_confirmation_activity.rb'
require_relative 'send_result_activity.rb'
```

現在，我們將建立類別，並提供某個初始化程式碼。

```
class ActivitiesPoller

  def initialize(domain, workflowId)
    @domain = domain
    @workflowId = workflowId
    @activities = {}

    # These are the activities we'll run
    activity_list = [
      GetContactActivity,
      SubscribeTopicActivity,
      WaitForConfirmationActivity,
      SendResultActivity ]

    activity_list.each do | activity_class |
      activity_obj = activity_class.new
      puts "** initialized and registered activity: #{activity_obj.name}"
      # add it to the hash
      @activities[activity_obj.name.to_sym] = activity_obj
    end
  end
```

除了儲存傳入的「網域」**和「任務清單」**之外，此程式碼還會實例化我們建立的每個活動類別。由於每個類別都會註冊其相關聯的活動 (`basic_activity.rb`如果您需要檢閱該程式碼，請參閱），這足以讓 Amazon SWF 知道我們將執行的所有活動。

對於每個實例化的活動，我們使用活動名稱 (例如 `get_contact_activity`) 做為索引鍵，將之存放於地圖上，因此可以使用接下來定義的活動輪詢器程式碼輕鬆地查詢這些活動。

建立名為 的新方法`poll_for_activities`，並在網域持有的 [activity\_tasks](https://docs.aws.amazon.com/AWSRubySDK/latest/AWS/SimpleWorkflow/Domain.html#activity_tasks-instance_method) 上呼叫[輪詢](https://docs.aws.amazon.com/AWSRubySDK/latest/AWS/SimpleWorkflow/ActivityTaskCollection.html#poll-instance_method)，以取得活動任務。

```
  def poll_for_activities
    @domain.activity_tasks.poll(@workflowId) do | task |
      activity_name = task.activity_type.name
```

從任務的 [activity\_type](https://docs.aws.amazon.com/AWSRubySDK/latest/AWS/SimpleWorkflow/ActivityTask.html#activity_type-instance_method) 成員可以取得活動名稱。接下來，我們將使用與此任務相關聯的活動名稱來查詢要執行 `do_activity` 的類別，並將任務傳遞給它 (包含應該傳送給活動的任何輸入資料)。

```
      # find the task on the activities list, and run it.
      if @activities.key?(activity_name.to_sym)
        activity = @activities[activity_name.to_sym]
        puts "** Starting activity task: #{activity_name}"
        if activity.do_activity(task)
          puts "++ Activity task completed: #{activity_name}"
          task.complete!({ :result => activity.results })
          # if this is the final activity, stop polling.
          if activity_name == 'send_result_activity'
             return true
          end
        else
          puts "-- Activity task failed: #{activity_name}"
          task.fail!(
            { :reason => activity.results[:reason],
              :details => activity.results[:detail] } )
        end
      else
        puts "couldn't find key in @activities list: #{activity_name}"
        puts "contents: #{@activities.keys}"
      end
    end
  end
end
```

程式碼只需等待 `do_activity` 完成，然後根據傳回碼，對任務呼叫 [complete\!](https://docs.aws.amazon.com/AWSRubySDK/latest/AWS/SimpleWorkflow/ActivityTask.html#complete!-instance_method) 或 [fail\!](https://docs.aws.amazon.com/AWSRubySDK/latest/AWS/SimpleWorkflow/ActivityTask.html#fail!-instance_method)。

**注意**  
此程式碼會在最終活動啟動後從輪詢器結束，因為它已完成其任務並啟動所有活動。在您自己的 Amazon SWF 程式碼中，如果您的活動可能再次執行，您可能想要讓活動輪詢器無限期地執行。

這是 **ActivitiesPoller** 類別的程式碼結尾，但我們將在檔案結尾再新增一些程式碼，以允許使用者從命令列執行它。

```
if __FILE__ == $0
  if ARGV.count < 1
    puts "You must supply a task-list name to use!"
    exit
  end
  poller = ActivitiesPoller.new(init_domain, ARGV[0])
  poller.poll_for_activities
  puts "All done!"
end
```

如果使用者從命令列執行檔案 (將活動任務清單做為第一個引數傳遞給它)，則此程式碼將會實例化輪詢器類別，並開始輪詢活動。輪詢器完成之後 (啟動最後一個活動之後)，就會列印訊息並結束。

活動輪詢器的運作就是如此。您只需要執行程式碼，並在「[訂閱工作流程教學：執行工作流程](swf-sns-tutorial-running-the-workflow.md)」中查看其運作方式。