web-dev-qa-db-ja.com

Flaskのapschedulerは2回実行されます

flaskアプリケーションでapschedulerを使用しているときに問題があります。

私のview.pyファイルで私はこのように書いています

import time
from apscheduler.scheduler import Scheduler

def test_scheduler():
     print "TEST"
     print time.time()


sched = Scheduler()
sched.add_interval_job(test_scheduler, seconds=5)
sched.start()

そして、このメソッドtest_scheduler()は5秒ごとに2回実行されます

テスト1360844314.01テスト1360844314.2

39
beka

私はそれを作りました、私はadd_interval_jobパラメータに追加して、特定の時点の後に開始します

sched.add_interval_job(test_scheduler, seconds=5, start_date='2013-02-13 00:00')
0
beka

デバッグモードでは、Flaskのリローダーがflask appを2回ロードします( 停止モードFlaskデバッグモードで2回初期化しないようにする方法) ) 。理由はわかりませんが、apschedulerのジョブが2回スケジュールされる原因になります。sched.start()の直前のprint "loaded scheduler"を使用すると、これを確認できます。

リンクされた回答で述べられているように、これにはいくつかの方法があります。私が最もうまくいったのは、次のようにリローダーを無効にすることです:

app.run(use_reloader=False)

それは私がそれを開発するときに私は自分のアプリを手動でリロードしなければならないことを意味しますが、apschedulerを動作させるために支払うことは少しの代償です。

50
Kenny Winker

リローダーを使用する場合、マスタープロセスと子プロセスがあります。スケジューラスレッドは両方で実行されます。マスタープロセスでスケジューラが実行されないようにする必要があります

if not app.debug or os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
  sched = Scheduler()
  sched.add_interval_job(test_scheduler, seconds=5)
  sched.start()
30
char101

Flaskの before_first_request() デコレータでスケジューラを開始できます。これは、「アプリケーションのこのインスタンスへの最初のリクエストの前に実行される関数を登録します "。

_import time
import atexit

from apscheduler.schedulers.background import BackgroundScheduler


def print_date_time():
    print(time.strftime("%A, %d. %B %Y %I:%M:%S %p"))


@app.before_first_request
def init_scheduler():
    scheduler = BackgroundScheduler()
    scheduler.add_job(func=print_date_time, trigger="interval", seconds=3)
    scheduler.start()
    # Shut down the scheduler when exiting the app
    atexit.register(lambda: scheduler.shutdown())
_

before_first_request()は、サーバーのリロード後の最初のリクエストで常に再度呼び出されることに注意してください。

11
tuomastik