IT業務効率化

digdagのsession_timeはcallの中でどうなるか

全てのtaskを同じ時間で実行したい

pythonのコードを連続してdigdagで実行するワークフローを構築したのですが、実行タイミングをpythonのdatetime.now()で構築してしまいました。

何が問題かというと、datetime.now()が実行された時間が基準となってしまうことです。

schedule:
  hourly>: 20:00

+parent_task:  # session_timeを元に実行する
  py>: print_date.print_now

+print_session_time_child:  # callしているworkflowもsession_timeで実行する
  call>: print_date_caller.dig

上のようなdigdagのworkflowが実行された時に、両方同じ時間で実行されるか確認してみました。

結論

session_timeはsessionが構築されたタイミングで生成され、callした先のworkflowも同じsession_timeで実行される。

検証過程

検証用のファイルを用意する

Pythonコード上で実行できることが大切なので、Python側でprintする。(shellでもrubyでも構わない。)

# -*- coding: utf-8 -*-
import time


class datetimeTest(object):
    def __init__(self):
        return

    def wait_10sec(self):
        print("wait 10 sec")
        time.sleep(10)
        print("wait done")

    def print_params(self, SESSION_TIME, called):
        print(f"called by {called}: {SESSION_TIME}")

wait_10secはあとでdigdagのファイルの中で利用します。

digdagでcallされるファイルは以下の様に用意しました。

timezone: Asia/Tokyo
+print_session_time:
  _export:
    SESSION_TIME: ${moment(session_time).format("YYYY-MM-DD HH:mm:ss")}
    called: child
  py>: bin.datetest.datetimeTest.print_params

これでprintされるときに呼び出される側のdigdagのファイルのsession_timeがchild: の後に出力されます。ファイル名はsession_time_test_child.digです。

次にメインのdigdagファイルを用意しました。

timezone: Asia/Tokyo
schedule:
  hourly>: 20:00
+print_session_time:
  _export:
    SESSION_TIME: ${moment(session_time).format("YYYY-MM-DD HH:mm:ss")}
    called: parent
  py>: bin.datetest.datetimeTest.print_params
+wait:
  py>: bin.datetest.datetimeTest.wait_10sec
+print_session_time_child:
  call>: session_time_test_child.dig

print_session_timeのタスクですぐに1回目のsession_timeを出力します。

そのあと10秒間待機して、session_time_test_child.digを呼び出します。callした先のsession_timeがどうなっているか確認します。

digdagのファイルをsession_timeを指定して実行する

digdag run session_time_test_parent.dig --session "2020-01-01 01:01:01"

digdagは–sessionでsession_timeを指定することができます。

実行結果

抜粋したものがこちらです。10秒間待って次のdigdagのファイルをcallした先でも同じsession_timeが使用されています。

$ digdag run session_time_test_parent.dig --session "2020-01-01 01:01:01"

called by parent: 2020-01-01 01:01:01

wait 10 sec

called by child: 2020-01-01 01:01:01

実際の実行結果が以下です。

$ digdag run session_time_test_parent.dig --session "2020-01-01 01:01:01"
2020-01-28 14:36:46 +0900: Digdag v0.9.35
2020-01-28 14:36:50 +0900 [INFO] (main): Using session /usr/local/digdag-server/digdag-demand_forecast/project/.digdag/status/20200101T010101+0900.
2020-01-28 14:36:50 +0900 [INFO] (main): Starting a new session project id=1 workflow name=session_time_test_parent session_time=2020-01-01T01:01:01+09:00
2020-01-28 14:36:53 +0900 [INFO] (0017@[0:default]+session_time_test_parent+print_session_time): py>: bin.datetest.datetimeTest.print_params
called by parent: 2020-01-01 01:01:01
2020-01-28 14:36:56 +0900 [INFO] (0017@[0:default]+session_time_test_parent+wait): py>: bin.datetest.datetimeTest.wait_10sec
wait 10 sec
wait done
2020-01-28 14:37:07 +0900 [INFO] (0017@[0:default]+session_time_test_parent+print_session_time_child): call>: session_time_test_child.dig
2020-01-28 14:37:08 +0900 [INFO] (0017@[0:default]+session_time_test_parent+print_session_time_child^sub+print_session_time): py>: bin.datetest.datetimeTest.print_params
called by child: 2020-01-01 01:01:01
Success. Task state is saved at /usr/local/digdag-server/digdag-demand_forecast/project/.digdag/status/20200101T010101+0900 directory.
  * Use --session <daily | hourly | "yyyy-MM-dd[ HH:mm:ss]"> to not reuse the last session time.
  * Use --rerun, --start +NAME, or --goal +NAME argument to rerun skipped tasks.
ABOUT ME
hirayuki
今年で社会人3年目になります。 日々体当たりで仕事を覚えています。 テーマはIT・教育です。 少しでも技術に親しんでもらえるよう、noteで4コマ漫画も書いています。 https://note.mu/hirayuki