概要
Workflowにて、並列処理をまたいでJobの実行順序を調整する手段について説明します。
NoticeBoardを使うことで、通常のFork処理では実現できない処理の連携を行います。
前提条件
- JS7 jobscheduler の環境準備、初期設定を済ませていること。
サンプルWorkflowを使ってざっと学習していることが望ましい。
まだの方はこちらから
JS7® JobScheduler 初期設定、サンプルWorkFlowの登録 - WorkFlowの作成、実行、ログ確認などの基本操作ができること。
こちらで簡単な操作説明をしています
JS7 JobScheduler 初めてのWorkFlow実行 - 本記事はJobScheduler Ver. 2.4.1 で確認した内容です。
今後内容が変わる可能性があります。
はじめに
本記事では、下図のような条件のWorkflowを定義します。
条件1: job1系(1a,1b)とjob2系(2a,2b) は並列で実行
条件2: job2bは、job1aとjob2aの両方が完了後に実行
条件1はFork処理での分岐と、順次処理の組み合わせで容易に定義できます。
しかし条件2は、単純にFork処理の機能だけでは定義できません。
※1a,2a の後で分岐を閉じ、再度1b,2bの分岐を書くこともできますが、並列度合いがいまひとつ。
(1aの処理が先に終わっても、2aが終了するまで1bが動かない)
そこで本例では、NoticeBoardを利用することで、この処理を実現する方法をご紹介します。
設定
Noticeboardの定義
Practice - Controller - Notice Boards と展開し、新規にNotice Boardを作成します。
名前はnotice_fork_custom_job1
としてください。
設定 | 値 |
---|---|
Name | notice_fork_custom_job1 |
Notice ID for posting order | replaceAll($js7OrderId, '^#([0-9]{4}-[0-9]{2}-[0-9]{2}#\w.+?)-.+?$', '$1') |
Notice ID for expecting order | replaceAll($js7OrderId, '^#([0-9]{4}-[0-9]{2}-[0-9]{2}#\w.+?)-.+?$', '$1') |
End of Life of Notice | 60 Seconds |
Workflowの定義
Practice - Controller - Workflows より、新規Workflow fork_custom
を作成します。
並列処理の追加
下記のとおり、Fork処理とJobを並べて並列処理を設定して下さい。
fork処理を追加して、2つに分岐 (branch1, branch2 を作成)
branch 1 側
Name/Label | (Shellジョブの)Script |
---|---|
job1a | sleep 10 |
job1b | sleep 5 |
branch 2 側
Name/Label | (Shellジョブの)Script |
---|---|
job2a | sleep 1 |
job2b | sleep 10 |
PostNocices/ExpectNocicesの追加
次に、job1a の後ろに、PostNotices処理を追加します。
Notice Board には、先ほど作ったnotice_fork_custom_job1
を選んでください。
※notice_fork_custom_job1
に通知を出します。
続いて、job2a の後ろに、ExpectNotices処理を追加します。
Notice Board には、先ほど作ったnotice_fork_custom_job1
を選んでください。
※notice_fork_custom_job1
の通知を待ちます。
終わりましたら、Deployしてください。
Workflowの動作確認
定義したWorkflow /Practice/fork_custom
を実行します。
各Jobの開始、終了時間を確認し、意図した順序でjobが実行されたことを確認してください。
時刻 | 動作 |
---|---|
19:34:42 | workflow 開始 |
19:34:44 | job1a、job2a が開始 |
19:34:45 | job2a が終了 (job2bはまだ開始されない) |
19:34:54 | job1a が終了 |
19:34:55 | job1b が開始(job1a終了直後に開始される) job2b が開始 (job1a,job2a の両方が終了した直後に開始される) |
19:35:00 | job1b が終了 |
19:35:05 | job2b が終了 (job1aの終了を待機した影響でjob2系が後に終わる) workflow 終了 |
各Jobのsleep時間を適当に調整し、想定通りの順序で動くか確認してみてください。
NoticeBoardの動作確認
RESOURCES - Notice Boards より、通知の内容を確認することが可能です。
job2a終了後、ExpectNotice処理が実行されると、NoticeBoard の設定に応じたIDの通知待ちとなります。
job1a終了後、PostNotice処理が実行されると、NoticeBoard の設定に応じたIDの通知が届きます。
また、Expectは該当IDの通知を受けたため、消えます。(後続のJob2bが開始されます)
End Of Life で設定した時間経過後、IDは自動的に削除されることを確認してください。
もしPost/Expect の連携がうまく動作しない場合は、このNotice Id が一致するように、NoticeBoardの設定を調整してください。
もし通知情報が残ったままの場合は、下記の操作で削除できます。
Post Notice の指定時間が長すぎて残ったままの場合
→ 上記メニュー上より Delete Notice
の操作
Expect Notice を消したい場合
→ 該当Workflowで ExpectNoticeで待ち状態となっているOrderをCancelで終了
【参考】NoticeBoardでの厳密なID指定
NoticeBoardで指定するNotice IDについて、デフォルトで2パターンが用意されています。
- Matching Daily Plan Dates
OrderId の日付部分 (#2022-11-08#T90515128805-root
→2022-11-08
) - Matching Daily Plan Dates and Order Name
OrderIdの日付+OrderName (#2022-11-08#T90515128805-root
→2022-11-08root
)
しかし、この2つの設定は、下記の問題があります。
- どちらのケースとも、当日中に何回実行しても、同じ Notice ID となってしまいます。
そのため、同日に複数回実行する場合には不向きです。 - OrderIdの日付部分は、手動Orderの場合、UTC日付、DailyPlanによるOrderの場合はJST(指定TimeZone)日付が入ります。
そのため手動実行の可能性がある場合、これらの設定はお勧めしません。 - 本記事のようにFork処理内でPostNotice,ExpectNoticeを使った場合、OrderName部分にはBranch名が含まれます。
そのため、同一Workflow内であっても、OrderIdやOrderNameは合致しません。- PostNoticeでのOrderIdの例:
#2022-11-08#T90515128805-root|branch2
- ExpectNoticeでのOrderIdの例:
#2022-11-08#T90515128805-root|branch1
- PostNoticeでのOrderIdの例:
そこで本記事では、Notice ID の取得に replaceAll($js7OrderId, '^#([0-9]{4}-[0-9]{2}-[0-9]{2}#\w.+?)-.+?$', '$1')
と指定しています。
この場合、OrderNameより前の箇所 2022-11-08#T90515128805
を取得でき、Order単位で一致させることができます。
厳密さにこだわらないならば、 post, expect ともに 適当な文字列(例えば 'id'
)でも、通知は可能です。※文字列はシングルクォートで囲う
【参考】End of Life of Notice について
End of Life of Notice は、処理内容に応じて適度な時間を指定してください。
例えば本記事の例では、End of Life of Notice
を1分指定で、仮にjob2aの処理時間に3分かかった場合、job2aの終了を待つ間に、通知が消えてしまいます。
また長すぎれば、期限切れまで通知が残り続けます。
【参考】複数処理の連携について
PostNotices, ExpectNotices とも、複数のNoticeBoardを指定できます。
またExpectNotices では、下記のように AND, OR の条件指定が可能です。
-
'notice_job_A' && 'notice_job_B'
job_A, job_B 両方の通知を受けた場合 -
'notice_job_A' || 'notice_job_B'
job_A, job_B どちらかの通知を受けた場合 -
( 'notice_job_A' && 'notice_job_B' ) || 'notice_job_C'
job_A, job_B の両方、または job_C 通知を受けた場合
これを使えば、さらに複数の分岐処理間の連携にも対応できます。
最後に
通常のNoticeBoardの使い方だと、複数Workflow間での連携処理を思い浮かべますが、本記事のように、同一Workflow内での使い方をマスターすれば、より柔軟なWorkflowを定義が実現できそうです。
参考
JS7 - Notice Boards
JS7 - PostNotices Instruction
JS7 - ExpectNotices Instruction
JS7 - Expressions for Variables