次の単純なパターンは、アプリケーションの更新後やハードで「不安定な」グーグルの失敗の後でもタスクシーケンスが停止しないようにするのに十分ですか。
def do_work():
... ....
deferred.defer(do_work, _countdown=..in 7 days..)
そのような自己スケジューリングワーカーをスケジュールして、決して振り返ることはできませんか?
次の単純なパターンは、アプリケーションの更新後やハードで「不安定な」グーグルの失敗の後でもタスクシーケンスが停止しないようにするのに十分ですか。
def do_work():
... ....
deferred.defer(do_work, _countdown=..in 7 days..)
そのような自己スケジューリングワーカーをスケジュールして、決して振り返ることはできませんか?
2つの答え:
はい、タスクは最終的に実行され、タスクの実行でエラーが発生した場合にも実行を再試行します。タスクを定義すると、再試行オプションが設定されます。
いいえ、タスクキューはスケジューラではないため、特定の時間に実行するタスクをスケジュールすることはできません。タスクキューに入れられたタスクは、FIFO方式で即座に処理されます。
@Jesseが指摘したように、ジョブをスケジュールするには、GAEcronを調べる必要があります。
タスクが正常にキューに入れられると、最終的に実行されます。(そして、App Engine は必要な限り試行を続けます)。
ただし、定期的にタスクを実行するcron ジョブを使用して、表示するパターンをより適切に実装できます。私が使用する一般的なパターンは、毎日の cron ジョブでタスク キューのタスクを開始し、再試行回数を少なくすることです (一時的な不具合が発生した場合は、すぐに再試行します)。
cron ではなく上記の方法を使用したい場合は、もう 1 つ心配することがあります。メソッドが失敗したり、他のシステムの問題 (たとえば、実行中のインスタンスがダウンしたり) により再試行される可能性があるためです。 2 つのタスクで終わらないでください。それが実行され、次のタスクが登録され、その後ノードがダウンした場合を想像してください。App Engine は再試行し、2 番目のタスクを開始します。これを防ぐには、(トランザクションで) データ ストアを使用して、次のタスクが既にキューに入れられているかどうかをテストして確認できます。何かのようなもの:
def do_work(counter):
...
@db.transactional
def start_next():
# fetch myModel from the data store here
if myModel.counter == counter:
return # already started next job
myModel.counter = counter
myModel.put()
deferred.defer(do_work, counter + 1, _transactional=True, _countdown=...)
start_next()
defer 呼び出しの「トランザクション」引数に注意してください。これにより、次のタスクがキューに入れられた場合にのみ MyModel インスタンスが更新されます。
また、再試行が一定回数失敗した後、管理者に電子メールを送信することを検討することもできます。(これはリクエスト HTTP ヘッダーで見つけることができますが、これを行う場合は遅延ライブラリを使用できません。タスク キュー API を直接使用する必要があります。)