我的任务可以从API中提取数据,然后就数据库(SQLITE)进行系统自动化(删除,重命名,...)。我设置了每5分钟执行一次的任务。但是,有时任务需要超过5分钟才能完成,因此两个任务并行运行。这不是很好,因为SQLite数据库在0分钟内锁定到该任务。
我该如何拥有
- 除非先前的任务已经完成或 ,否则任务将不会执行
- 第二个任务排队并在0分钟任务完成后直接执行?
我试图使用全局布尔来防止执行任务,如这样。
automate_is_running = False
@periodic_task(run_every=timedelta(minutes=5))
def automate():
if not automate_is_running:
automate_is_running = True
automate_all()
automate_is_running = False
,但这返回UnboundLocalError: local variable 'automate_is_running' referenced before assignment
错误。我该怎么办?
开始,您必须在功能中使用global
。但这仍然无法按照您的意愿工作,因为每个芹菜工人都是其自己的过程,并且数据之间没有共享数据。
您需要使用某种外部静音,例如磁盘上的文件或DB或CACHE中的条目。芹菜食谱中有一个使用模式的示例。
而不是定期安排一次,并始终在任务结束时安排下一个执行。还要确保要重述失败的任务。
错误 TypeError: automate() missing 1 required positional argument: 'self'
是因为芹菜task
装饰器创建一个任务对象,因此您需要接受它的实例为firs参数 self
。
以下代码将尽快运行任务,然后在任务成功完成后始终300秒。它也将在失败时尽快重试。
要立即触发任务,请用self.delay()
替换self.apply_async(countdown=300)
或通过countdown=0
。
@task
def automate(self):
try:
automate_all()
except Exception as exc:
raise self.retry(exc=exc)
else:
self.apply_async(countdown=300)
automate.delay()
尝试使用Specyfif异常类而不是Exception
。我不知道您的代码会做什么以及您期望的例外。
您可以在第一个任务结束时设置带有芹菜节的调度程序,并调用第二个任务。
芹菜(芹菜2.3)
from django.conf import settings
from celery.schedules import crontab
settings.CELERYBEAT_SCHEDULE = {
'runs-every-5-minutes' : {
'task': 'automate',
'schedule': crontab(minute='*/5'),
'args' : (),
},
}
tasks.py:
from celery import task
@task(name='automate')
def automate():
automate_all()
run_second_task()
文档:
芹菜2.3:http://docs.celeryproject.org/en/v2.3.3/userguide/periodic-tasks.html#crontab-schedules
芹菜4.1http://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html#crontab-schedules