5
3

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 5 years have passed since last update.

Digdagのscheduleとrequireの関係

Posted at

Digdag Release 0.9.37 で確認。

TL;DR

  • requireオペレータを安易に利用していたらsession_timeが競合して死んだ
  • session_timeとschedule設定の仕様を正しく理解しましょう
  • 公式ドキュメントは読みましょう

何が起こったか

1日1回ずつ動かしたい2つのワークフロー[A.dig/B.dig]から共通のdigファイル[C.dig]をrequireする設計で運用を開始。
が、 なぜか片方だけが動作していない…。
それぞれのdigファイルの中身はこんな感じ。

A.dig
schedule:
  daily>: 08:30:00
  skip_on_overtime: true
  skip_delayed_by: 1s

~~

+require-C:
  require>: C.dig
B.dig
schedule:
  daily>: 18:00:00
  skip_on_overtime: true
  skip_delayed_by: 1s

~~

+require-C:
  require>: C.dig
C.dig
+main:
  sh>: hoge.sh

原因は何だったか

A.dig、B.digともにdailyオプションでschedule指定をしていたため、session_timeが両者ともに00:00:00 となっていた。
requireは親となるワークフローのsession_timeで子ワークフローを起動する ため、C.digが同一のsession_timeで2回呼び出されることとなり、時系列順で後の処理が不発となっていた。

挙動をまとめてみる

When you use hourly, daily, weekly or monthly, a session time may not be same with actual run time.
The session time is actual run day’s 00:00:00 (in case hourly, hour’s 00:00).

  • requireについて
    requireの際にデフォルトで子ワークフローに自分のsession_timeを渡す挙動についてはドキュメント中に確認できませんでした。
    下記のワークフローを用意して検証します。

| workflow_name | schedule |
|:--|:--|:--|
| Parent1 | hourly>: 10:00 |
| Parent2 | hourly>: 15:00 |
| Parent3 | cron>: 20 * * * * |
| Parent4 | minutes_interval>: 11 |
| Child1 | N/A |
| Child2 | hourly>: 40:00 |
| Child3 | cron>: 45 * * * * |
| Child4 | minutes_interval>: 13 |

各Childは自身のsession_timeを出力するだけのワークフロー。
各Parentが全ての各Childをrequireしています。
結果が以下。(mm:ssのみ記載)

workflow_name itself required by Parent1 required by Parent2 required by Parent3 required by Parent4
Child1 N/A 00:00 00:00 20:00 11*N:00
Child2 00:00 00:00 00:00 20:00 11*N:00
Child3 45:00 00:00 00:00 20:00 11*N:00
Child4 13*N:00 00:00 00:00 20:00 11*N:00

やはり親のsession_timeが使われるようです。

補足1) Child2についてはParent1(またはParent2)が同一session_timeで先に起動してしまうため、Child2自身のスケジュールで起動することはありません。
補足2) Parent4とChild4は00:00のsession_timeが競合します。cron記法に則り00:00がスケジュールの起点となるため。

  • callについて
    callオペレータを使った場合も親のsession_timeに準じますが、親のサブタスクとなるのでそのsession_timeで子ワークフローが実行されたという記録は残りません。
    また、公式ドキュメントにもあるように多重実行制御は行われません。

解決

多重実行制御してくれる便利なrequire!callの上位互換!という誤った認識を改めcallオペレータに置き換えました。
またはcronパラメータに置き換えてもいいはずです。むしろ最初からcronパラメータだけを使うのが安全かもしれません。
さらなる解法としてrequire時にsession_timeをオプションとして明示的に渡す方法もあります。
多重実行制御を行いたい、かつhourly等のパラメータを使いたいという場合は工夫が必要でしょう。そんなケースは思い当たりませんが。

参考

Digdagのrequireオペレーターの挙動
https://qiita.com/shiozaki/items/b3aaff926b7b601b4f86 参考にさせていただきました。

公式ドキュメントがもうちょっと充実してくれるといいなー。

5
3
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
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?