LoginSignup
51
41

More than 5 years have passed since last update.

APSchedulerで少し進んだジョブスケジューリング

Posted at

APSchedulerで少し進んだジョブスケジューリング

理由と目的と動機

  • cronで10分に一回くらいのジョブを回すのが限界に来てしまった。
  • 前の処理が10分以上掛かると多重起動になってしまうから。これを防止したい。
  • 何らかの ロック機構 を使えば・・・と思ったのだが、それをジョブのコード中に入れるのは避けたい。
    • そのジョブが対象となるロック機構依存になってめんどくさい。
    • テストが大変でバグの元。
  • 起動しているのはpythonのジョブなので、できればpythonで書かれているものはないのか・・・

多重起動を防止できるジョブスケジューラ探し

  • APShcedulerがあった!
  • pythonで実装されてる。
  • 多重起動を防止できる。
    • 多重起動の許可と幾つまでOKかも指定できる。
  • cronライクなジョブスケジューリング可能。
  • atコマンドの様に指定の時間に一回の起動も可能。
  • cronより細かい、秒単位のジョブスケジューリングもできる。
  • 本家のドキュメントはこちら

インストール

pipかeasy_installで。

$ easy_install apscheduler
または
$ pip install apscheduler

ジョブスケジューラを書いてみる

  • インターバルの秒数を指定して起動するタイプのスケジューラを実装してみる。
import apscheduler.scheduler as ApSched

def job_function():
    print "Hello World"

sched = ApSched.Scheduler(standalone=True,coalesce=True)
sched.add_interval_job(job_function, seconds=10)
sched.start()

standaloneオプションはデフォルトFalse。Trueにするとスケジューラ自身がdaemonicに動く。

試しにipythonで実行してみた結果。

In [18]: 2013-11-26 16:12:32.680493
Hello World
In [18]: 2013-11-26 16:12:42.680962
Hello World
In [18]: 2013-11-26 16:12:52.680975
Hello World

尚、ちゃんとプログラムの実行時間を抜いてインターバル時間を計算してくれている。

多重起動防止の実験

from apscheduler.scheduler import Scheduler
import datetime
import time

def job_function_13sec():
    print datetime.datetime.today()
    time.sleep(13)
    print "Hello World"

sched = Scheduler(standalone=True,coalesce=True)
sched.add_interval_job(job_function_13sec, seconds=10)
sched.start()

結果。

In [46]: sched.start()
2013-11-26 16:36:10.818178
WARNING:apscheduler.scheduler:Execution of job "job_function_13sec (trigger: interval[0:00:10], next run at: 2013-11-26 16:36:30.817553)" skipped: maximum number of running instances reached (1)
Hello World
2013-11-26 16:36:30.818776
WARNING:apscheduler.scheduler:Execution of job "job_function_13sec (trigger: interval[0:00:10], next run at: 2013-11-26 16:36:40.817553)" skipped: maximum number of running instances reached (1)
Hello World
2013-11-26 16:36:50.818992
WARNING:apscheduler.scheduler:Execution of job "job_function_13sec (trigger: interval[0:00:10], next run at: 2013-11-26 16:37:10.817553)" skipped: maximum number of running instances reached (1)
Hello World
2013-11-26 16:37:10.818815
WARNING:apscheduler.scheduler:Execution of job "job_function_13sec (trigger: interval[0:00:10], next run at: 2013-11-26 16:37:30.817553)" skipped: maximum number of running instances reached (1)
Hello World
2013-11-26 16:37:30.818828

ジョブのオプションとして デフォルトでmax_runが1 なので、多重起動を防止してくれている。

その後

  • cronの様に常時動かすためにsupervisordでデーモン化しました。
  • プロセスが死んでも自動再起動でご安心。
  • しかしクラッシュしたらメールを飛ばすようにしたい・・・。うーあー。イベントリスナーとかの機能で行けそう。
51
41
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
51
41