[Talend] Flow, Iterate, Trigger についてのまとめ

2015.12.18

Talend Studio でジョブを作成する際に避けて通れないのがコンポーネントとコンポーネントの紐付けです。この紐付けはコンテキストメニュー上で七種類に分別されています。

Row メイン
反復
トリガ サブジョブがOKの場合
サブジョブがエラーの場合
条件付き実行の場合
コンポーネントがOKの場合
コンポーネントがエラーの場合

これら「紐付け」について性質の違いや使用局面をまとめてみました。

コンポーネント間の接続

Talend Studio ではこれらの紐付け(関連線)を用いてコンポーネントとコンポーネントを紐付けてジョブを作成していきます。私はコンポーネントに使われている単語などから引用して関連線の種類を「Flow」「Iterate」「Trigger」の三種類に大別しています。

Flow について

コンテキストメニューで「Row > メイン」と呼ばれている関連線です。

talend-flow-iterate-trigger_001

上図では「オレンジ色」の「row1 (Main)」などと描かれた線になります。

性質
  • スキーマ定義が必要なコンポーネントに接続される。
  • talend-flow-iterate-trigger_004

  • 接続先のコンポーネントへ「行データ」を渡す。
  • Flow 関連線で繋がれたコンポーネントはまとめて1行ずつ処理される。

Iterate について

コンテキストメニューで「Row > 反復」と呼ばれている関連線です。

talend-flow-iterate-trigger_008

上図では「明るい緑色」の「Iterate」と描かれた線になります。

性質
  • スキーマ定義を持たないコンポーネントに接続される。
  • 主に接続先のコンポーネントは「元コンポーネントが保持する値」を参照する。
  • talend-flow-iterate-trigger_009 ※ここでは「tFileList_1」の「CURRENT_FILEPATH」を参照しています。(この値は Studio のコード補完機能を用いて容易に入力できます。)

Trigger について

コンテキストメニューで「トリガ」に含まれている関連線です。

talend-flow-iterate-trigger_003

上図では全ての線が Trigger であり、

  • 「緑色」の「OnComponentOk」と描かれた線は「コンポーネントがOKの場合」
  • 「濃い緑色」の「OnSubjobOk」と描かれた線は「サブジョブがOKの場合」
  • 「茶色の破線」の「If」と描かれた線は「条件付き実行の場合」

となります。(ここではエラー系は除外しています。)

性質
  • コンポーネント間の接続にあまり制限は無い。(割となんでも接続可)
  • 「コンポーネントがOKの場合」は接続元コンポーネントが正常終了した場合に接続先コンポーネントが処理される。
  • 「サブジョブがOKの場合」は接続元コンポーネントを内包するサブジョブ(薄水色の領域)全体が正常終了した場合に接続先コンポーネントが処理される。
  • talend-flow-iterate-trigger_006

  • 「条件付き実行の場合」は関連線に書かれた Java コードの結果が true の場合のみ接続先コンポーネントが処理される。
  • talend-flow-iterate-trigger_007

エラー系の Trigger も考え方は「OK」と同様になります。

処理のかたち

Flow, Iterate, Trigger の各処理がどのような Java コードとなるのか調べてみました。

Flow as Java

talend-flow-iterate-trigger_001

簡略化した処理コード(実際のコードとは異なります。)
for (generatedRecord: generatedRecords) {

    row1.col1 = generatedRecord.col1;
    row1.col2 = generatedRecord.col2;
    row1.col3 = generatedRecord.col3;

    // row1 に対して tJavaRow_1 の処理を実施
    row2.col1 = row1.col1;
    row2.col2 = row1.col2;
    row2.col3 = row1.col3;

    // row2 に対して tLogRow_1 の処理;
    コンソールへ出力(row2.col1, row2.col2, row2.col3);
    
}

Iterate as Java

talend-flow-iterate-trigger_008

簡略化した処理コード(実際のコードとは異なります。)
int numberOfFile = 0;

for (file : files) {

    numberOfFile++;
    globalMap.put("tFileList_1_CURRENT_FILE", file.name);
    globalMap.put("tFileList_1_CURRENT_FILEPATH", file.path);
    globalMap.put("tFileList_1_CURRENT_FILEDIRECTORY",file.directory);
    globalMap.put("tFileList_1_CURRENT_FILEEXTENSION", file.extension);
    globalMap.put("tFileList_1_NB_FILE", numberOfFile);

    // tJava_1 の処理を実施
    String foo = "bar";

    // file.path の値で tFileCopy_1 の処理を実施
    ファイルをコピー((String) globalMap.get("tFileList_1_CURRENT_FILEPATH"), "/Users/inage.toru/");

}

Trigger as Java

talend-flow-iterate-trigger_003

簡略化した処理コード(実際のコードとは異なります。)
private void tJava_1Process(final Map<String, Object> globalMap) {

    // tJava_1 の処理を実施
    TalendLogger.info(jobName, "tJava_1 処理");

    // tJava_2 の処理を呼び出し
    tJava_2Process(globalMap);

}

private void tJava_2Process(final Map<String, Object> globalMap) {

    // tJava_2 の処理を実施
    TalendLogger.info(jobName, "tJava_2 処理");

    // tJava_3 の処理を呼び出し
    tJava_3Process(globalMap);

    // 条件式が true の場合に tJava_4 の処理を呼び出し
    if (true) {
        tJava_4Process(globalMap);
    }

    // tJava_5 の処理を呼び出し
    tJava_5Process(globalMap);

}

private void tJava_3Process(final Map<String, Object> globalMap) {

    // tJava_3 の処理を実施
    TalendLogger.info(jobName, "tJava_3 処理");

}

private void tJava_4Process(final Map<String, Object> globalMap) {

    // tJava_4 の処理を実施
    TalendLogger.info(jobName, "tJava_4 処理");

}

private void tJava_5Process(final Map<String, Object> globalMap) {

    // tJava_5 の処理を実施
    TalendLogger.info(jobName, "tJava_5 処理");

}

まとめ

関連線について、現状私は以下のように考えるようにしています。

Flow

  • スキーマが定義されるコンポーネント間を繋ぐ際に用いられる。
  • Flow 関連線(オレンジ色の線)の始端コンポーネントから終端コンポーネントまでの処理が単一の繰り返し処理(for 文)となる。
  • 繰り返し処理の中ではひとつの行データが各コンポーネントで定義されたスキーマの形へ変化しながら始端から終端へ流れる。
  • スキーマを持たないコンポーネントへ処理を接続する場合には「tFlowToIterate」コンポーネントを用いて「反復(Iterate)」へ変換する。

Iterate

  • 始端コンポーネントが「反復(Iterate)」を出力するコンポーネント(ex. tFileList など)の場合に用いられる。
  • Iterate 関連線(明るい緑色の線)の始端コンポーネントから終端コンポーネントまでの処理が単一の繰り返し処理(for 文)となる。
  • スキーマが存在しないことから分かるように行(Row)データは流れないため、コンポーネントは特定のコンポーネントが持つグローバル変数を参照することで処理を繋いでいく。
  • Iterate 処理中のデータにスキーマ構造を持たせ行(Row)データとしてスキーマを持つコンポーネントへ処理を接続する場合には「tIterateToFlow」コンポーネントを用いる。

Trigger

  • データの受け渡しなどはせずに別の処理単位へ繋ぐ(「A を B する処理から C を D する処理へ」のような)場合に用いられる。
  • 接続先コンポーネントは別メソッドとして定義され接続元コンポーネントの処理内から呼び出される形となる。
  • 「サブジョブがOKの場合」は、接続元コンポーネントの処理内の最後に呼び出されるようになる。

紐付けが複雑になると生成される Java コードはこの限りでは無いかもしれません。
どのように処理が遷移していくか不明瞭な場合は、「コードビュー」に切り替えて生成された Java コードを眺めてみると良いと思います。