okochangの馬鹿でありがとう

ふらふら適当に世間を生きる日々でございます

Ruby版 AWS Flow Frameworkのチュートリアルをやってみた

こんにちは@oko_changです。
先日Simple Workflow Service用のRubyフレームワークであるAWS Flow Frameworkリリースされたので、今回はこれについて書いてみようと思います。
SWFについては以下のドキュメントが参考になると思います。

チュートリアル

今回やってみたことはDeveloper GuideのGetting Started: "Hello, World!"ですが、英語版のビデオチュートリアルもあり内容はどちらもほぼ同じです。

サンプルプログラムのダウンロード

こちらからサンプルプログラムのダウンロードが出来ます。
ダウンロードしたファイルを解凍するとSamplesディレクトリがあり、サンプルプログラムがいくつかあります。

$ tree Samples/
Samples/
├── Booking
│   └── lib
│       ├── booking_activity.rb
│       ├── booking_workflow.rb
│       ├── booking_workflow_starter.rb
│       ├── credentials.cfg
│       └── utils.rb
├── Cron
│   └── lib
│       ├── credentials.cfg
│       ├── cron_activity.rb
│       ├── cron_starter.rb
│       ├── cron_workflow.rb
│       └── utils.rb
├── Deployment
│   └── lib
│       ├── application_stack.yml
│       ├── credentials.cfg
│       ├── deployment_activity.rb
│       ├── deployment_types.rb
│       ├── deployment_workflow.rb
│       ├── deployment_workflow_starter.rb
│       └── utils.rb
├── HelloWorld
│   └── lib
│       ├── aws-config.txt
│       ├── hello_activity.rb
│       ├── hello_workflow.rb
│       ├── hello_world.rb
│       ├── kill_hello.rb
│       ├── run_hello
│       └── utils.rb
├── Periodic
│   └── lib
│       ├── credentials.cfg
│       ├── error_reporting_activity.rb
│       ├── periodic_activity.rb
│       ├── periodic_workflow.rb
│       ├── periodic_workflow_options.rb
│       ├── periodic_workflow_starter.rb
│       └── utils.rb
└── README.md

10 directories, 32 files

AWS Flow Frameworkのインストール

インストールは以下のような感じです。

$ gem install aws-flow

サンプルプログラム

今回はHelloWorldのサンプルを動かしてみたい思うので、HelloWorldディレクトリ内のlib/aws-config.txt内にアクセスキーIDとシークレットアクセスキーを入力します。

---
:access_key_id: "your access key id"
:secret_access_key: "your secret access key"

HelloWorldのサンプルはその名の通りスクリーンにHello Worldを入力するようなサンプルで、以下のようなもので構成されています。

  • アクティビティ
  • ワークフロー
  • スターター

AWSの認証やSWFドメインの作成、タスクリストの設定などはlib/utils.rbで行われています。

require 'aws/decider'

$HELLOWORLD_DOMAIN = "HelloWorld"
config_file = File.open('aws-config.txt') { |f| f.read }
AWS.config(YAML.load(config_file))

$SWF = AWS::SimpleWorkflow.new

begin
  $HELLOWORLD_DOMAIN = $SWF.domains.create($HELLOWORLD_DOMAIN, "10")
rescue AWS::SimpleWorkflow::Errors::DomainAlreadyExistsFault => e
  $HELLOWORLD_DOMAIN = $SWF.domains[$HELLOWORLD_DOMAIN]
end

# Set up the workflow/activity worker
$TASK_LIST = "hello_world_task_list"

次にアクティビティの処理に関してはlib/hello_activity.rbで行われています。

require_relative 'utils'

class HelloWorldActivity
  extend AWS::Flow::Activities

  activity :hello_activity do
    {
      :default_task_list => $TASK_LIST, :version => "my_first_activity",
      :default_task_schedule_to_start_timeout => 30,
      :default_task_start_to_close_timeout => 30
    }
  end

  def hello_activity(name)
    puts "Hello, #{name}!"
  end
end

activity_worker = AWS::Flow::ActivityWorker.new($SWF.client, $HELLOWORLD_DOMAIN, $TASK_LIST, HelloWorldActivity) { {:use_forking => false} }

# Start the worker if this file is called directly from the command line.
activity_worker.start if __FILE__ == $0

次にワークフロー作成の処理はlib/hello_workflow.rbに記載されております。

require_relative 'utils'
require_relative "./hello_activity"

class HelloWorldWorkflow
  extend AWS::Flow::Workflows

  workflow :hello_workflow do
  {
    :version => "1", :execution_start_to_close_timeout => 3600, :task_list => $TASK_LIST
  }
  end

  activity_client(:activity) { {:from_class => "HelloWorldActivity"} }

  def hello_workflow(name)
    activity.hello_activity(name)
  end
end

worker = AWS::Flow::WorkflowWorker.new($SWF.client, $HELLOWORLD_DOMAIN, $TASK_LIST, HelloWorldWorkflow)
# Start the worker if this file is called directly from the command line.
worker.start if __FILE__ == $0

ワークフローを起動するスターターはlib/hello_world.rbに記述されています。

require 'aws/decider'
require_relative 'utils'
require_relative 'hello_workflow'

# Get a workflow client to start the workflow
my_workflow_client = AWS::Flow.workflow_client($SWF.client, $HELLOWORLD_DOMAIN) do
  {:from_class => "HelloWorldWorkflow"}
end

puts "Starting an execution..."
workflow_execution = my_workflow_client.start_execution("AWS Flow Framework for Ruby")

サンプルプログラムの実行

lib/run_helloがbashスクリプトになっているので、libディレクトリに移動して実行すればOKです。

#!/bin/bash
ruby hello_activity.rb &
ruby hello_workflow.rb &
ruby hello_world.rb

サンプルプログラムの停止

こちらもkill_hello.rbというスクリプトが用意されていますし、エラーになるようであれば各プロセスをkillします。

まとめ

マイスターシリーズを読みつつサンプルプログラムを読むとイメージがつかめやすいなぁと思いました。
とはいえやっぱり実際に自分で書いてみるほうが良いですね。