特定の間隔で特定の間隔で実行するタスクをhereから設定することができますが、これはタスク宣言時にのみ行われます。定期的に動的に実行するタスクを設定するにはどうすればよいですか?あなたは、あなたが新しい作成後のX秒のために何かを実行したい例えばDdjango celery:特定の間隔でプログラムで実行するようにタスクを設定する方法
:
特定の間隔で特定の間隔で実行するタスクをhereから設定することができますが、これはタスク宣言時にのみ行われます。定期的に動的に実行するタスクを設定するにはどうすればよいですか?あなたは、あなたが新しい作成後のX秒のために何かを実行したい例えばDdjango celery:特定の間隔でプログラムで実行するようにタスクを設定する方法
:
スケジュールはderived from a settingであり、実行時に不変であるようです。
あなたはおそらくTask ETAsを使用して探しているものを達成することができます。これにより、の前にの時間が実行されませんが、指定された時間にタスクを実行することはできません。指定されたETAで作業者が過負荷になった場合、タスクは後で実行されます。
その制限が問題でない場合は、あなたが最初のように自分自身を実行しますタスク書くことができます:
@task
def mytask():
keep_running = # Boolean, should the task keep running?
if keep_running:
run_again = # calculate when to run again
mytask.apply_async(eta=run_again)
# ... do the stuff you came here to do ...
をこのアプローチの主要な欠点は、あなたが仕事を覚えてtaskstoreに依存しているということです飛行中。そのうちの1つが次のタスクを実行する前に失敗すると、そのタスクは決して再び実行されません。ブローカがディスクに永続化されておらず、そのブローカが(実行中のすべてのタスクを使って)死んだ場合、それらのタスクはどれも実行されません。
これらの問題は、何らかの種類のトランザクションログと定期的な "nanny"タスクによって解決できます。このタスクでは、間に合わない死を迎えて復活させるような繰り返しタスクを見つけることです。
あなたが説明したことを実装しなければならない場合は、これが私のアプローチに近いと思います。
は、私はあなたが動的に作ることができないと思いますhttp://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html
こちらをご覧ください...最善の方法は、タスクにタスクを作成することですこのタスクでは、N * X秒遅れの別のタスクを作成します。
celery.task.base.PeriodicTask
は、次の実行がいつ行われるかを決定するis_due
を定義します。この関数をオーバーライドして、カスタム動的実行ロジックを含めることができます。カスタムスケジュールを定義したらhttp://celery.readthedocs.org/en/latest/faq.html#can-i-change-the-interval-of-a-periodic-task-at-runtime
...これはあなたにいくつかのを助けるべき
import random
from celery.task import PeriodicTask
class MyTask(PeriodicTask):
def run(self, **kwargs):
logger = self.get_logger(**kwargs)
logger.info("Running my task")
def is_due(self, last_run_at):
# Add your logic for when to run. Mine is random
if random.random() < 0.5:
# Run now and ask again in a minute
return (True, 60)
else:
# Don't run now but run in 10 secs
return (True, 10)
、asksolが持っているとして、あなたのタスクに割り当て:http://docs.celeryproject.org/en/latest/reference/celery.task.base.html?highlight=is_due#celery.task.base.PeriodicTask.is_due
例:ここではドキュメントを参照してください。上記で提案された。
CELERYBEAT_SCHEDULE = {
"my_name": {
"task": "myapp.tasks.task",
"schedule": myschedule(),
}
}
また、あなたはあなたのスケジュールをより頻繁に5分ごとよりも更新したい場合はCELERYBEAT_MAX_LOOP_INTERVALを変更したい場合があります。
はい、スケジューラは動的スケジュール用に最適化されていませんが、上記のように 'schedule'を' is_due'メソッドで実装することもできます。また、タスク再スケジュール自体は多くの用途に使用できます最初のタスクが常に起動されるようにします。これは簡単ではありません。もう一つの選択肢は、django-celeryでDatabaseSchedulerを使用することです。これは動的スケジュールをサポートし、Djangoプロジェクトの外でも使用できます。さらに、独自のスケジューラを作成することはそれほど難しいことではありません。 – asksol
@asksol、django-celeryのドキュメントは空です。databaseSchedulerの使い方はどこで知ることができますか? – goh
@amateur文書は実際にはほんのわずかです。 – asksol