Xplenty中級編 Part6: ワークフロー機能について

このブログでは、Xplentyのワークフロー機能とは何で、どういう時に使うか、そしてどのようにして依存関係のあるETLタスクをより効率的に管理することができるのかについて説明します。

#ワークフローとは？
概念的には、「ワークフロー」とは、タスクを希望の実行順序に並べることができる特別なタイプのパッケージです。ワークフローの「タスク」は、既存のDataflowパッケージまたはSQLクエリ操作のいずれかになります。ドラッグアンドドロップのインターフェースにより、希望する実行順序でタスクを配置することができます。

Xplentyのワークフローの主要な機能は以下の通りです。

##1) 実行結果のステータスに応じて異なる実行パスをトリガする

ワークフローでは、2つのタスク間の実行関係に基づいて、2つのタスクを追加・接続することができます。つまり、先行するタスクの実行状況に応じて、異なるパスのタスクを実行することができます。簡単な例を挙げてみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/2353ecaa-7ab8-3250-04fd-c2e3774013b2.png)
Xplentyがサポートしている実行結果のステータスは以下の３つです。 

- on success
- on failure
- on completion

上の図のワークフローを実行すると、dataflow_task(Dataflowパッケージを実行する)が最初に実行されます。タスクが完了するとpost_completion_queryが実行され、タスクの成否に応じてpost_failure_queryまたはpost_success_queryが実行されます。

##2)先行タスクの実行状況に基づく実行条件（制御）の追加

ワークフローでは、前のタスクの実行状況に基づいて、任意のタスクに条件付きロジックを追加することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/15bd7190-5fe6-2188-9662-aa9dbfae7fa4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/0b4fde36-b5a0-76ed-1cc6-05ebc5c7deda.png)

「いずれか(OR）」または「すべて」(AND)の実行条件をタスクに追加することができます。上の図で定義したワークフローでは、「AND」条件が設定されており、dataflow_task_1 と sql_query_1 の両方が正常に実行された場合にのみ、dataflow_task_2が実行されます。dataflow_task_2に「OR」条件を選択していた場合、dataflow_task_1またはsql_query_1のいずれかが正常に実行された場合に実行されます。

上記の２つの機能を組み合わせることで、パッケージを特定の順番で実行させたい場合(AがBの前、BがCの前、CがDの前など)、それらの実行がそれぞれのタスクの成功や完了に依存している複雑な実行プロファイルをモデル化することができます(Aが失敗したらBを実行し、BとCの両方が成功したらDを実行するなど)。

##3) タスク実行時に使用する動的な変数を渡す
Dataflowパッケージと同様に、ワークフローにも変数スコープがあります。変数がDataflowパッケージレベルで定義されている場合、その値が使用され、Dataflowパッケージで変数の定義が見つからない場合、Xplentyはワークフローレベルの変数を参照します。これらのワークフロー変数は、ワークフロー作成時に設定し、ジョブやスケジュール経由で実行する際に、それらの設定画面で変数を上書くことができます。  
ただし、ワークフロー変数とデータフロー変数の両方が同じ名前の場合は、ワークフロー変数をデータフロー変数に変数画面で割り当てる必要があります。（詳細は後述の[こちら](https://qiita.com/Azabu10ban/items/e44bd53ed75818626b3a#%E5%8F%82%E8%80%83-workflow%E3%83%AC%E3%83%99%E3%83%AB%E3%81%AE%E5%A4%89%E6%95%B0%E3%81%A8dataflow%E3%81%AE%E5%A4%89%E6%95%B0%E3%81%AE%E9%96%A2%E4%BF%82%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)を参照。）
ワークフロー内の SQLタスクは、値（クエリ結果）を返すことができ、それをスカラー値を含むワークフロー変数に保存することができます。この値は、後続のSQLタスクやDataflowパッケージタスクに渡すことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/d865eb32-79df-7bb5-5c4f-cd1e53d20450.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/67c62b28-3337-1884-6593-aa1b09a77f5e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/1a42538b-9453-43bf-7e03-94d2e61c1a69.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/7a50674a-84df-adb0-ab94-ebda5a42bf94.png)

上記のワークフローでは、最初の SQL クエリ タスクは、まだ公開されていないアクティブなプロモーションをチェックします。そのようなプロモーションがある場合、その識別子は変数 active_promotion_id に格納されます（デフォルトでは、返された結果の最初の行の最初の列の値が格納されます）。そして、この識別子はpublish_promoパッケージのDataflowパッケージ変数に渡されます。最後に、パッケージの実行が成功した場合、プロモーションをデータベースで公開されたものとしてマークするクエリタスクがあります。このクエリは同じ識別子を使用してデータベース内のプロモーションを見つけます。 

#ワークフロー使用例
Xplentyを使用しているEコマース企業は、ビジネスを改善するために定期的にマーケティングキャンペーンやプロモーションを行っています。キャンペーンを開始するには、いくつかの準備タスクを実行しなければならず、キャンペーンが終わった後、いくつかの調整タスクを実行したいと思うかもしれません。

ワークフローを定義する方法としては、次のようなものが考えられます。

- データベースで SQL クエリを実行して、現在ローンチ予定のキャンペーンがあるかどうかをチェックします。キャンペーン識別子をワークフロー変数に保存します。
- アクティブなキャンペーンがある場合、エンゲージメント数値を収集するためのテーブルの作成、ランディングページCRMのバナーコンテンツの更新、他の従属サービス（PDP、顧客など）のデータベースの更新、一括でのメール通知の準備と送信、ターゲット顧客のためのキャッシュウォーミング活動の実行などのETLタスクをトリガーします。最初に保存したキャンペーン識別子変数は、これらの後継タスクに渡されます。
- これらの相互依存のタスクは、正しい順序で実行されるように配置されています（Bootstrapのデータテーブル→ランディングページのバナーを更新→キャッシュウォーミング→一括メール通知を生成）。
これらのタスクのいずれかが失敗した場合、データベース（SQLクエリ）に失敗ステータスを保存する、タスクを再スケジュー リングする、または診断を実行するAPIを呼び出すなどのアクションをトリガーするリカバリータスクがあるかもしれませんが、状況について関係するチームに警告することができます。すべてのタスクが正常に実行された場合にも、同様のアクションを定義することができます。
- ワークフロー内には、最近期限切れになったキャンペーンがあるかどうかを検出し、後の分析のためにメトリクスを集計したり、クリーンアップを実行するタスクをスケジューリングする SQL クエリタスクを追加することができます。
一度構築されたワークフローは、定期的に（例えば、毎日夜11:30に）実行するようにスケジューリングすることができ、相互に依存する異なるタスクが手動で介入することなく連携して実行されます。

これまでに説明したワークフロー機能とは別に、その他の便利な機能についてもいくつか紹介します。

- ワークフロー内で使用するタスクは、Dataflowパッケージとしてそれ自体で完結する１つの処理として定義することができます。これにより、モジュール化し、メンテナンスしやすい実装を行うことができ、それぞれのチームやメンバーに効率的に作業を割り当てることができます。
- ワークフローは、実装の複雑さを抽象化しながら、これらのタスクが正しい順序で実行されるように配置します。これにより、様々なシステムがどのように相互作用するかを俯瞰的に見ることができます。
- バージョン管理されているので、問題が発生した場合には、以前のバージョンに切り替えることができます。
- Xplentyのダッシュボードでは、ワークフローの実行状況を監視したり、失敗の通知を受けたり、スケジュールを変更したりすることができます。
- こうした仕組みを自社で維持するのは、非常に時間とリソースを消費します。システムには、データベース接続の管理、cron式と複数のプロセスの維持、依存関係の設定、アラートシステムの追加などを含みます。Xplentyは、既存のワークフローにブレンドできる使いやすいローコードのインターフェイスを通して、これらすべてを提供します。

#参考： Workflowレベルの変数とDataflowの変数の関係について
Workflowパッケージレベルの変数は、Dataflowレベルの変数を上書く（オーバーライド）のに使用することができます。

###例1: Workflow変数（Workflow側で設定した変数）とDataflow変数で同じ名前の変数を定義した場合
タスクでWorkflow変数をDataflowに適用する場合、Workflow内の各タスク設定画面でDataflow変数に代入する必要があります。（ワークフロー変数とデータフロー変数の両方が同じ名前の場合は、ワークフロー変数をデータフロー変数に割り当てる必要があります。）


タスクで指定したデータフローで、データフローレベルでは変数が定義されていないが、ワークフローレベルで定義されている変数がデータフローパッケージ内で使用されている場合、データフロー・タスクはワークフロー変数の値を使用します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/ddd50ca0-9563-9a92-29cf-745c9f4e7722.png)


###例2: Workflowレベルでのみ変数が定義されている場合
Workflow内のDataflow（タスク）がそのDataflow内で定義されていない変数を使用していた場合でも、Workflowレベルで値がセットされている場合、そのDataflowタスクは、Workflow変数の値を使用して実行されます。
以下の場合、Dataflowレベルの実行は失敗しますが、Workflowを実行すると正しく動作します。
Dataflow `$today`変数定義なし *ただし、ソースコンポーネントのフィルタ条件に「CratedAt>$today」といった文字列を使用
Workflow `$today`変数あり



###変数の表記に注意: 
SQL内での変数の指定方法: **「${変数名}」**
通常パッケージ内のURLやファイルパスなど:**「$変数名」**

#まとめ
Xplentyのワークフロー機能はシンプルですが、非常に役に立つ機能です。ワークフローの使い方の詳細は[こちらのヘルプ](https://www.xplenty.com/docs/creating-a-workflow/)でご確認いただけます。