訪問者に情報を提供する Web サイトを構築しています。この情報は、5 秒ごとにいくつかの外部 API をポーリングすることによって、バックグラウンドで集計されます。私が今それを機能させている方法は、APSchedulerジョブを使用することです。システム全体の移植がより簡単になるため、最初は APScheduler を好みました (新しいマシンで cron ジョブを設定する必要がないため)。次のようにポーリング機能を開始します。
from apscheduler.scheduler import Scheduler
@app.before_first_request
def initialize():
apsched = Scheduler()
apsched.start()
apsched.add_interval_job(checkFirstAPI, seconds=5)
apsched.add_interval_job(checkSecondAPI, seconds=5)
apsched.add_interval_job(checkThirdAPI, seconds=5)
これはちょっとうまくいきますが、いくつかの問題があります:
- 手始めに、これは間隔ジョブが Flask コンテキストの外で実行されていることを意味します。これまでのところ、これは大きな問題ではありませんでしたが、エンドポイントの呼び出しが失敗したときに、システムからメールが送信されるようにしたいと考えています (「API X の呼び出しに失敗しました」というメッセージ)。ただし、Flask コンテキスト内で実行されないため、flask-mailを実行できないと訴えます (
RuntimeError('working outside of application context')
)。 - 第 2 に、Flask 組み込みデバッグ サーバーを使用しなくなったときに、これがどのように動作するのか疑問に思いますが、4 つのワーカーを使用する運用サーバーとしましょう。それでは、すべてのジョブを 4 回開始しますか?
全体として、これらの定期的なタスクを実行するためのより良い方法があるはずだと感じていますが、その方法はわかりません。誰かがこの問題に対する興味深い解決策を持っていますか? すべてのヒントは大歓迎です!
[編集] Celeryとそのスケジュールについて読んでいます。Celery が APScheduler とどのように違うのか、それによって私の 2 つのポイントを解決できるのかどうかはよくわかりませんが、これを読んで、Celery についてもっと調査する必要があると思う人がいるのだろうか?
[結論] 約 2 年後、私はこれを読んでいて、最終的にどうなったかを皆さんにお知らせできると思いました。@BluePeppers が Flask エコシステムにそれほど密接に結び付けられるべきではないと言ったのは正しいと思いました。そこで、Ansible を使用して設定された、毎分実行される通常の cron ジョブを選択しました。これにより少し複雑になりますが (Ansible を学習し、毎分実行するだけで十分になるようにコードを変換する必要がありました)、これはより堅牢だと思います。私は現在、a-sync ジョブ (API のチェックと電子メールの送信) をキューに入れるために素晴らしいpythonr-rqを使用しています。rq-schedulerについて知りました。まだテストしていませんが、そもそも私が必要としていたことを正確に実行しているようです。したがって、これはこの質問の将来の読者へのヒントになるかもしれません。
残りは、皆さんの素晴らしい一日をお祈りします!