我有一项任务是从API中提取数据,然后针对数据库(SQLite)进行系统自动化(删除,重命名......)。我将任务设置为每5分钟执行一次。但是,有时任务完成需要5分钟以上,因此两个任务并行运行。这不好,因为SQLite数据库在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
错误。我该怎么办?
答案 0 :(得分:0)
首先,您必须在函数中使用global
。但是这仍然不能按你的意愿工作,因为每个Celery工作者都有自己的流程,而且流程之间不共享数据。
您需要使用某种外部互斥锁,例如磁盘上的文件或db或缓存中的条目。有一个使用memcached的示例in the Celery cookbook。
答案 1 :(得分:0)
不是使其定期,而是在开始时安排一次,并始终在任务结束时安排下一次执行。还要确保重试失败的任务
错误TypeError: automate() missing 1 required positional argument: 'self'
是因为Celery task
装饰器创建了一个任务对象,因此您需要接受它的实例作为第一个参数self
。
以下代码将尽快运行任务一次,然后在任务成功完成后始终运行300秒。它也会在失败时尽快重试
要立即再次触发任务,请将self.apply_async(countdown=300)
替换为self.delay()
或传递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()
尝试使用specyfic异常类而不是Exception
。我不知道你的代码做了什么以及你期望的例外。
答案 2 :(得分:0)
您可以设置芹菜节拍的调度程序,并在第一个任务结束时调用您的第二个任务。
celery.py(Celery 2.3)
custom.css
tasks.py:
from django.conf import settings
from celery.schedules import crontab
settings.CELERYBEAT_SCHEDULE = {
'runs-every-5-minutes' : {
'task': 'automate',
'schedule': crontab(minute='*/5'),
'args' : (),
},
}
文档:
芹菜2.3: http://docs.celeryproject.org/en/v2.3.3/userguide/periodic-tasks.html#crontab-schedules 芹菜4.1 http://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html#crontab-schedules