AWS SimpleWorkflow を使おう(Part1: 概要、何故SimpleWorkflowなのか)

# 目次
- AWS Simple Workflow とは
- なぜ Aws Simple Workflow なのか

[表参道rb#12でSWFとMicroservicesについて発表](https://speakerdeck.com/haito/microservices-in-aws-simple-workflow-swf)して、SWF使おう！はやってないけど！みたいな話をしました。
そうしたら、お前がまず広めていってSWFの人になればいいよ、みたいな意見を貰ったので、全く流行ってないと思われるSimple WorkflowについてOutputしていこうと思います。ちゃんとサンプルコードとか載せていきたいです(夢想)

> あと、間違ってたことがあったら言ってください！(予防線)

# Aws Simple workflow とは
## 概略的な何か
Amazon Web Service が提供するワークフローを構築するためのサービスです。
[大体今回書く話はこのスライドに書いてある気がします](http://www.slideshare.net/AmazonWebServicesJapan/amazon-simple-workflow-service-swf)
ここでいうワークフローとは、いわゆる業務フローみたいなものです。~~大嫌いな~~ あまり好きではない出張のためのスタンプラリーとか、工場のラインとかそういうモノです。

Aws Simple Workflow(以下SWF) ではワークフローを設計、コーディングする為のライブラリを提供し、ワークフローを動作させるためのQueueやAPIやユーティリティを提供します。

また、本質的にはSWFはJSONをやりとりするAPI通信さえできれば言語は問わないので、任意の言語でSWFを用いてワークフローを作ることが出来ます。

## SWFにおける用語等について
| 用語 | 意味 |
|:-----------|:---------------|
| Workflow | 実行する一連の処理全て |
| Domain | Workflow を実行する領域。あんまりこれの意味がわからない。多分業務ドメイン |
| ActivityType | Workflowを構成する、処理を表す |
| AcitivtyWorker | ActivityTaskを実際に処理するワーカー |
| Decider | ActivityTaskが処理された後に、次の処理を決定するワーカー |
| WorkflowExecution | Workflowを流れる、処理されるタスク |
| ActivityTask[^1] | ActivityWorkerに処理をされる為のWorkflowExecution |
| DecitionTask[^1] | Deciderに処理をされる為のWorkflowExecution |

> この方の記事のほうがわかりやすい気がします。→ http://qiita.com/uzresk/items/5401e8617d628f0ef9a9
> タスクという言葉が多いけど、僕が上手に抽象化できていないことの現れ

## SWFを使った処理の流れ
<img width="969" alt="スクリーンショット 2016-06-11 18.39.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/37097/c3f975ec-42ea-ce8f-92e6-32c5b2faf539.png">
### 文字起こし
1. まず何かしらが`WorkflowExecution`をスタートさせ、`DecistionTasks`(`DeicitionTask`のQueue)に積みます
2. `DeciderWorker`が`DecitionTasks`をPoolingしているので、`DeciderWorker`がまず`WorkflowExeuction`を取得します。
3. `DeciderWorker`が`WorkflowExeuction`が次にいくべき`ActivityType`を知っているので、`WorkflowExecution`の情報を見て決定し、該当の`ActivityType A`のQueue(`ActivityTasks`)にEnqueueします。
4. `ActivityTasks`をPoolingしている`ActivityWorker`が`WorkflowExecution`を取得し、処理を行います
5. `ActivityWorker`は処理の結果や付随させたい情報等を`WorkflowExecution`に書き込み、完了通知と共に`DecisionTasks`にEnqueueします。
6. `DeciderWorker`は相変わらず`DecisionTasks`をPoolingしています
7. `3` と同様に次の`ActivityType`を決定します。今度は`ActivityType A`が完了しているという情報が`WorkflowExecution`に詰まっているので、`ActivityType B`の`ActivityTasks`にEnqueueします。
8. これまた同様に、`ActivityWorker`は`ActivityTasks`をPoolingしているので、Dequeueして処理を行います。
9. ここで処理を完了したいので、`WorkflowExecution`を完了させます。

### SWFが提供してくれること、AWS-SDKが提供してくれること
上記画像において、SWFのIconがある部分がAWSが処理を担ってくれる部分です。
また、SWFのIconに向かう矢印の操作はSDKが提供してくれています。
よって、最低限開発者が実装すべき点は以下です。

1. 「XXという状態の`WorkflowExectuion`の場合は、次はこの`ActivityType`へいく」という判断をする`Decider`
2. `ActivityTasks`をpoolingして、処理を実際に実行する`ActivityWorker`

*意外と*シンプルなように*見えますね*

# なぜ SWF なのか
[Amazon Simple Workflow Casual Talk by Kenichi TAKAHASHI](https://speakerdeck.com/kenchan/amazon-simple-workflow-casual)
殆どは↑のスライドに詰まっています。

更に補足すると、SWFの最も優れていると考えているのは以下の点においてです。

1. SWFとのやりとり、SWF内でのやりとりは全て一意のトランザクションIDが振られており、追跡、失敗、復旧が容易
2. SWFとのやりとり、SWF内でのやりとりにおける全てのEventは記録されており、追跡、分析が容易
3. SWFのAPIを叩け、JSONを扱うことさえできれば言語も場所も問われないため、複数アーキテクチャ上から利用することも出来る
4. スライドでも言及されているが、`ActivityType`内での処理において人の手によって完了される事を想定されており、その完了を待つことが出来る。

- 上記特性のため、Queueからの受信は一回のみ（な、はず。何回か「同じ`ActivityTask`を取得したとしか思えないエラー」に出会った記憶が……)
- 全てのEvent[^2]が記録され、且つそのEventにトランザクションIDを付与し続ける事が出来るので、`ActivityType`内での処理も適切にロギングできれば全ての行動を追跡出来る。
- ユースケースとして、オンプレミスとクラウドの共存状態が想定されているので、言語やアーキテクチャを問わないのはSWFのシステム上目指している事っぽい。

## 人の手によって完了される事を想定している？
工場のラインを考えるとわかりやすいです。
自動化されている部分は、全てのプログラム上で処理が進んでいき、`ActivityTask`の取得から完了まで自動で行えばよいです。
しかし、目見チェックなどが必要な工程になったら、人が処理を完了させるまで次の工程に進んではいけません。
同じことを実現する事が出来るということです。
> というか、ユースケースとしてこういう業務上のワークフローを想定していると思う。

# 次回予告
ここまではチュートリアル記事とかにも書いてあったりして、日本語記事も多いです。
今回は概要についてのみでしたが、深い実装の話とか今後していきたいと思います。

## 一応
Sansanでは名刺のデータ化において、一日数十万の`WorkflowExecution`を処理しています。
[(自称)世界一のSWFユーザーであるSansanはエンジニアを募集しています。](http://jp.corp-sansan.com/recruit/job/engineer_ruby.html)
> なんかデータ化の部署の募集要項が公式HPにないんですけど……

[^1]: `WorkflowExecution`の別名です。誰に扱われているのか、を明確にするときに使います。
[^2]: 全てのEventとは、「スタートされた」「XXXのQueueに積まれた」「XXXのQueueからDequeueされた」とかに始まり「XXXの`ActivityType`でStartされた後Timeoutした」とか全ての状態遷移のEventです。