2017-09-25 128 views
0

我有一个任务,从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错误。我该怎么办?

+0

那么首先,你必须在函数中使用'global'。但是,这仍然不能按需要工作,因为每个Celery工作人员都是自己的进程,数据不会在进程之间共享。您需要使用某种外部互斥锁,例如磁盘上的文件或db中的条目。 –

+0

或者您可能只有一个工作人员一次只运行一项任务,或者甚至为每项任务设置一个时间限制。请参阅此处的配置:http://docs.celeryproject.org/en/latest/userguide/configuration.html –

回答

0

一开始,你必须在功能中使用global。但是,这仍然不能按需要工作,因为每个Celery工作人员都是自己的进程,数据不会在进程之间共享。

您需要使用某种外部互斥锁,例如磁盘上的文件或数据库或缓存中的条目。有一个使用memcached的例子in the Celery cookbook

+0

已经查看示例,但我无法理解它。我只有一个没有任何必要参数的函数,'automate()'。但是这个例子有'self'参数,我不确定什么是重要的。 – notalentgeek

+0

另外,我有这个错误TypeError:automate()缺少1个需要的位置参数:'self'。 – notalentgeek

+0

这只是一个例子。如果你的任务不是一个类的方法,不要使用'self'。 –

0

不是将其定期,而是在开始时安排一次,并始终在任务结束时安排下一次执行。还要确保重试失败的任务。
错误TypeError: automate() missing 1 required positional argument: 'self'是因为芹菜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。我不知道你的代码的作用和你期望的例外。

0

您可以设置一个芹菜拍的调度程序,并在第一个任务结束时调用第二个任务。

celery.py(芹菜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.1 http://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html#crontab-schedules

相关问题