2023年8月11日金曜日

rqscheduler でジョブの実行結果を保存する期間を指定する

rqscheduler でジョブの実行結果を保存する期間を指定する

概要

result_ttl をジョブ登録時に指定します
ただ最初に注意事項として記載しますが result_ttl を設定するとジョブのキー自体が削除されて再スケジュールされなくなるので注意してください

例えば1分おきのジョブを登録した場合に result_ttl=10 (10秒) に設定すると一度ジョブが実行されて10秒後にジョブ自体が消えてしまうので次の1分後にジョブが実行されなくなります

環境

  • Python 3.11.3
  • flask-rq2 18.3
  • rq-scheduler 0.13.1

サンプルコード

前回からのを流用しているのでインタフェースは Flask になります
ポイントは scheduler.cron 時に result_ttl を設定するところです

  • vim ./app.py
from flask import Flask, request
from flask_rq2 import RQ
from rq.job import Job

app = Flask(__name__)
app.config["RQ_REDIS_URL"] = "redis://localhost:6379/0"

rq = RQ(app)


def hello():
    return "hello"


@app.route("/update")
def update_job():
    job_id = request.args["job_id"]
    cron_string = request.args.get("cron_string", "*/2 * * * *")
    scheduler = rq.get_scheduler(queue="bar")
    job = Job.fetch(job_id, connection=scheduler.connection)
    job.meta["cron_string"] = cron_string
    job.save_meta()
    return {"id": job.id, "cron_string": job.meta.get("cron_string")}


@app.route("/")
def get_jobs():
    scheduler = rq.get_scheduler(queue="bar")
    jobs = scheduler.get_jobs()
    return [
        {
            "id": job.id,
            "cron_string": job.meta.get("cron_string"),
            "results": [
                f"{r.type}:{r.return_value}:{r.created_at}" for r in job.results()
            ],
        }
        for job in jobs
    ]


@app.route("/register")
def register_job():
    scheduler = rq.get_scheduler(queue="bar")
    job = scheduler.cron(
        "*/1 * * * *",
        func=hello,
        args=[],
        result_ttl=10,  # ここを追加、単位は秒
    )
    return job.get_id()

ちなみに redis 上では rq:results:xxx というキーに stream 型で保存されます
return_value は base64 エンコードされています

127.0.0.1:6379> type rq:results:2064a66f-b2cf-4e42-962d-e71d9313a4bd
stream
127.0.0.1:6379> xrange rq:results:2064a66f-b2cf-4e42-962d-e71d9313a4bd - +
1) 1) "1691107781067-0"
   2) 1) "type"
      2) "1"
      3) "return_value"
      4) "gAWVCQAAAAAAAACMBWhlbGxvlC4="
2) 1) "1691107841069-0"
   2) 1) "type"
      2) "1"
      3) "return_value"
      4) "gAWVCQAAAAAAAACMBWhlbGxvlC4="
3) 1) "1691107901019-0"
   2) 1) "type"
      2) "1"
      3) "return_value"
      4) "gAWVCQAAAAAAAACMBWhlbGxvlC4="

対策方法

幸いにも結果を保存するキーは別なので単純にそれだけ定期的に削除するようにすればいいかなと思います

127.0.0.1:6379> del rq:results:2064a66f-b2cf-4e42-962d-e71d9313a4bd

もしかするとそれをやってくれる API が rq にあるかもしれません

最後に

冒頭も記載しましたがジョブ (redis のキー自体) がなくなるので注意しましょう
公式にもありますが cron ジョブでは基本的には result_ttl=-1 で無期限かかなり長めの値を設定するのがいいようです

参考サイト

0 件のコメント:

コメントを投稿