1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

JS7® JobScheduler 複数Workflowの同期実行

Last updated at Posted at 2022-11-09

概要

複数のWorkflowを決まった順番で実行する同期実行の方法について説明します。
WorkflowのAddOrder処理と、NoticeBoardの機能を使った連携方法です。

前提条件

  • JS7 jobscheduler の環境準備、初期設定を済ませていること。
    サンプルWorkflowを使ってざっと学習していることが望ましい。
    まだの方はこちらから
    JS7® JobScheduler 初期設定、サンプルWorkFlowの登録
  • WorkFlowの作成、実行、ログ確認などの基本操作ができること。
    こちらで簡単な操作説明をしています
    JS7 JobScheduler 初めてのWorkFlow実行
  • NoticeBoard の基本的な使い方を理解していること。
    サンプルWorkflow中の処理や、こちらの記事を学習していると理解しやすいと思います。
    JS7® JobScheduler 複数Workflowの同期実行
  • 本記事はJobScheduler Ver. 2.4.1 で確認した内容です。
    今後内容が変わる可能性があります。

はじめに

Workflow処理の利用に慣れると、Workflowの定義数が増えていきます。
さらに、これらのWorkflowを、決まった順序で実行したいと考えるようになると思います。
image.png

単一Workflowにすべての処理を詰め込めば、順次処理は可能です。
しかしこの手段では、Job数の増加とともに、全体の見通しが悪くなり、特定の処理だけ修正、実行することも困難です。
※Ver. 2.4より、開始/終了Job指定が可能だが、数が多いと扱いづらい。
image.png

特定Workflowから、他のWorkflow処理を実行する手段として、AddOrder処理があります。
しかし、こちらは非同期処理となります。
※呼び出したWorkflowの終了を待たずに、後続処理が進んでしまう。
そのため各Workflowが同時に実行されてしまう。
image.png

そこで本記事では、NoticeBoardを利用することで、呼び出したWorkflowの終了を待ってから、次の処理に進む手段をご紹介します。
image.png

この手段ならば、各Workflowを決まった順序で実行することができます。
もちろん各Workflowは、通常どおり個別に実行することも可能です。

設定

実際に簡単な設定を行ってみます。
以降は、Workflowを呼び出す側を親Workflow、呼び出される側(実際の処理を行う側)を子Workflowとします。

親Workflowから、2つの子Workflowを順次実行する設定を作成してみます。

NorticeBoard定義

まずは、2つの子Workflow用に、それぞれのNoticeBoardを作成します。

Practice - Controller - Notice Boards と展開し、新規にNotice Boardを作成します。
名前はnotice_sub_Aとしてください。

値は下記のように設定します。
image.png

設定
Name notice_sub_A
Notice ID for posting order replaceAll($js7OrderId, '^#[0-9]{4}-[0-9]{2}-[0-9]{2}#.*?-(.+?)!.+?$', '$1')
Notice ID for expecting order replaceAll($js7OrderId, '^#([0-9]{4})-([0-9]{2})-([0-9]{2})#\w(.+?)-.+?$', '$1$2$3$4')
End of Life of Notice 60 Seconds

設定できましたら、Deployしてください。


全く同じ設定で、notice_sub_Bを作成、Deployしてください。(Copy、Pasteで可)

設定
Name notice_sub_B
Notice ID for posting order replaceAll($js7OrderId, '^#[0-9]{4}-[0-9]{2}-[0-9]{2}#.*?-(.+?)!.+?$', '$1')
Notice ID for expecting order replaceAll($js7OrderId, '^#([0-9]{4})-([0-9]{2})-([0-9]{2})#\w(.+?)-.+?$', '$1$2$3$4')
End of Life of Notice 60 Seconds

子Workflowの定義

つぎに、呼び出される側の2つの子Workflowを作成します。
※今回はサンプルとして、簡単な処理で済ませます。

Practice - Controller - Workflows より、新規Workflow SyncExec_sub_A を作成します。
適当なJobと、最後にPostNoticesを追加してください。
image.png

Jobの項目
Name/Label job
Agent primaryAgent
JobClass Shell
Script sleep 10
PostNoticesの項目
Notice Board Names notice_sub_A

設定できましたら、Deployしてください。


同じく子WorkflowSyncExec_sub_Bを作成します。
こちらの PostNotices は、notice_sub_Bを指定します。

Jobの項目
Name/Label job
Agent primaryAgent
JobClass Shell
Script sleep 10
PostNoticesの項目
Notice Board Names notice_sub_B

設定できましたら、Deployしてください。

NorticeBoardの動作確認

子WorkflowSyncExec_sub_Aを実行し、NorticeBoardnotice_sub_Aに通知が飛ぶことを確認します。
image.png
さらに、指定時間(60秒)経過後、自動的に通知が消えることを確認します。
image.png

※この時点では、ExpectNoticesの指定がないため、まだ連携処理はありません。
※Notice Id は、OrderId 値がそのまま入っていますが、この時点では問題ありません。

同様に、子WorkflowSyncExec_sub_B、NorticeBoardnotice_sub_Bでも確認をしてください。

親Workflowの定義

最後に親Workflowの定義を行います。

Practice - Controller - Workflows より、新規Workflow SyncExec_main を作成します。

まず、sub_A用の処理を定義します。
Job, AddOrder, ExpectNotices の処理を並べてください。

image.png

設定は下記のようにおこなってください。

Jobの項目
Name/Label start_sub_A
Agent primaryAgent
JobClass Shell
Script echo "SyncExec_sub_A" ※処理は適当でよい
AddOrderの項目
Workflow Name SyncExec_sub_A
ExpectNoticesの項目
Notice Board Names
(ExpectNotices Expression)
'notice_sub_A'

sub_Aの後続に、sub_B用の処理を同じように追加します。

image.png

設定は下記のようにおこなってください。

Jobの項目
Name/Label start_sub_B
Agent primaryAgent
JobClass Shell
Script echo "SyncExec_sub_B" ※処理は適当でよい
AddOrderの項目
Workflow Name SyncExec_sub_B
ExpectNoticesの項目
Notice Board Names
(ExpectNotices Expression)
'notice_sub_B'

終わりましたら、Deployしてください。

親Workflowの動作確認

親Workflow/Practice/SyncExec_mainを実行します。
ログの実行時間を見て、2つのWorkflowが順次実行されたことを確認してください。

image.png

時刻 動作
14:22:51 親Workflow 開始
14:22:52 子Workflow SyncExec_sub_A 開始
14:23:02 子Workflow SyncExec_sub_A 終了
子Workflow SyncExec_sub_B 開始
14:23:12 子Workflow SyncExec_sub_B 終了
14:23:13 親Workflow 終了

NorticeBoardの動作確認

親Workflow/Practice/SyncExec_mainを実行します。
すると、まず親Workflowにて、子WorkflowSyncExec_sub_A のOrder追加が行われます。
そのままsub_A用のExpectNotice処理が実行され、NoticeBoard notice_sub_Aでは、IDの通知待ちとなります。
image.png

子Workflow SyncExec_sub_A終了時に、PostNotice処理が実行され、NoticeBoard notice_sub_Aでは、IDの通知が届きます。
また、sub_A用のExpectはIDの通知を受けたため、消えます。(後続の処理が開始されます)
さらに、後続のsub_B用のOrder追加、ExpectNotice処理が実行され、NoticeBoard notice_sub_Bでは、IDの通知待ちとなります。
image.png

子Workflow SyncExec_sub_B終了時に、PostNotice処理が実行され、NoticeBoard notice_sub_では、IDの通知が届きます。
また、sub_B用のExpectはIDの通知を受けたため、消えます。(親Workflow終了)
image.png

End Of Life で設定した時間経過後、IDは自動的に削除されることを確認してください。
image.png

もしPost/Expect の連携がうまく動作しない場合は、このNotice Id が一致するように、NoticeBoardの設定を調整してください。

並列実行の場合

複数の子Workflowを並列実行する場合は、複数のAddOrderパーツを並べます。
非同期で処理が進むため、ほぼ同時並行で実行されます。
※AddOrderは、単一Orderしか対応できません

image.png

Workflow名: SyncExec_multi

Jobの項目
Name/Label start_sub
Agent primaryAgent
JobClass Shell
Script echo "SyncExec_sub" ※処理は適当でよい
AddOrderの項目
Workflow Name SyncExec_sub_A
AddOrderの項目
Workflow Name SyncExec_sub_B
ExpectNoticesの項目
ExpectNotices Expression 'notice_sub_A' && 'notice_sub_B'

設定できましたら、Deployし、動作確認してみてください。
2つのWorkflowが同時並行で実行されたことが確認できます。
image.png

時刻 動作
14:54:14 親Workflow 開始
14:54:15 子Workflow SyncExec_sub_A 開始
子Workflow SyncExec_sub_B 開始
14:54:25 子Workflow SyncExec_sub_A 終了
子Workflow SyncExec_sub_B 終了
親Workflow 終了

ExpectNotices では、下記のように AND, OR の条件指定が可能です。

  • 'notice_sub_A' && 'notice_sub_B' sub_A, sub_B 両方の通知を受けた場合
  • 'notice_sub_A' || 'notice_sub_B' sub_A, sub_B どちらかの通知を受けた場合
  • ( 'notice_sub_A' && 'notice_sub_B' ) || 'notice_sub_C' sub_A, sub_B の両方、または sub_C 通知を受けた場合

これにより、各Workflowがすべて終了した場合、一部のみ終了した場合などの指定が可能です。
※PostNoticeでも、複数NoticeBoardへの通知が可能

【参考】NoticeBoardでの厳密なID指定

本記事のように、AddOrder処理を行う場合、OrderIdは下記のようになります。

  • 親WorkflowのOrderID : #2022-11-09#T97195741002-root ※expectに利用
  • 子WorkflowでのOrderID : #2022-11-09#D97195781200-2022110997195741002!-root ※postに利用

※親OrderIdの日付、数値列が、子OrderIDの後ろについている。

そこで本記事では下記の設定でNotice Idを指定しています。

Notice ID for posting order : replaceAll($js7OrderId, '^#[0-9]{4}-[0-9]{2}-[0-9]{2}#.*?-(.+?)!.+?$', '$1')
Notice ID for expecting order : replaceAll($js7OrderId, '^#([0-9]{4})-([0-9]{2})-([0-9]{2})#\w(.+?)-.+?$', '$1$2$3$4')

  • 親Workflowでは、ExpectNoticeで、OrderID より、2022, 11, 09 , 97195741002 を結合した2022110997195741002を待つ
  • 子Workflowでは、PostNoticeで、OrderId の後部分の数値列 2022110997195741002 を通知する

この設定ならば、親WorkflowのOrderIDでつながるため、より確実かと思います。

本記事の例では、Idは適当な文字列(例えば 'id' )で済ませ、End of Life of Notice を数秒にするのも有効です。
※PostNotice後、即ExpectNoticeで処理が動くため、短時間での同時実行がなければ、必ずしも厳密なIdである必要はありません。

なお、デフォルトで用意されている設定でNotice Idを指定することは、個人的にはお勧めしません。

  • Matching Daily Plan Datesは、Idが日付となるため、複数のOrderでIdが重複する。1日に何度も実行する場合には不向き。
  • Matching Daily Plan Dates and Order Name は、上記に加え、Order Name が指定しづらい。

OrderId中の日付は、手動OrderではUTC日付、Workflow中のAddOrderや、DailyPlanではJST日付(TimeZone設定による)となります。
そのため手動Orderを行う場合、実行時間帯によっては不一致となります。

【参考】親WorkflowにJobを追加する理由

親Workflowで、何故Jobstart_sub_A, start_sub_Bを追加するのか疑問をもたれた方もいるかと思います。

1つ目の理由として、WorkflowにJobを1つも追加しないままでは、Deployがうまくできない問題があります。
そのため、適当なJobを1つ以上追加する必要があります。

2つ目の理由として、万が一途中の子Workflowがエラーとなり、途中から再実行したい場合、分かりやすいJob名があれば、多くの処理の中から、開始位置を容易に選ぶことができます。(運用上の利便性)

image.png

これらの理由で、子Workflow開始前に、それを示すJobを配置することをお勧めします。

【参考】Slack通知の簡略化

本記事の方法で複数のWorkflowを実行した場合、各子Workflowおよび親Workflowが終了するたび通知が飛びます。
この場合、例えば下記の設定で、正常終了時は、親Workflowの完了通知だけで済ませることができます。

子Workflowでは、Order変数で、is_notify (Boolean) = true を定義
image.png

親Workflowでは、AddOrder時に、is_notify = false を指定
image.png

Notification 中の 該当CommandFragment設定にて、最初に下記のような条件指定を追加
image.png

# Order変数 is_notify = false かつ正常終了時は通知しない
[ "$(echo '${MON_O_START_VARIABLES}' |jq -r .is_notify)" == "false" ] && [ ${MON_N_STATUS} == 0 ] && exit

Monitor変数${MON_O_START_VARIABLES}では、Order追加時に変数を指定した場合に、json形式で変数値を取得できます。
これを用いて、Order変数 is_notify=falseかつ${MON_N_STATUS}=0(正常終了)の場合は処理を抜けるように設定します。
※JOCにて、jqコマンドが使えることを確認してください。docker版では別途追加が必要です。

最後に

本記事の方法を用いることで、各Workflowを部品化でき、設定をすっきりさせることができます。
また、スケジュールによる各Workflowの順次実行と、状況に応じた個別実行の、両方に対応できます。
Workflowの利用が増えた際の整理手段として、参考にしていただければ幸いです。

参考

JS7 - AddOrder Instruction
JS7 - Notice Boards
JS7 - How to make a job wait for completion of a workflow

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?