4

次の単純なパターンは、アプリケーションの更新後やハードで「不安定な」グーグルの失敗の後でもタスクシーケンスが停止しないようにするのに十分ですか。

def do_work():
    ... .... 

    deferred.defer(do_work, _countdown=..in 7 days..)

そのような自己スケジューリングワーカーをスケジュールして、決して振り返ることはできませんか?

4

2 に答える 2

2

2つの答え:

はい、タスクは最終的に実行され、タスクの実行でエラーが発生した場合にも実行を再試行します。タスクを定義すると、再試行オプションが設定されます。

いいえ、タスクキューはスケジューラではないため、特定の時間に実行するタスクをスケジュールすることはできません。タスクキューに入れられたタスクは、FIFO方式で即座に処理されます。

@Jesseが指摘したように、ジョブをスケジュールするには、GAEcronを調べる必要があります。

于 2012-09-08T14:00:12.400 に答える
1

タスクが正常にキューに入れられると、最終的に実行されます。(そして、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 を直接使用する必要があります。)

于 2012-09-08T13:39:01.100 に答える