我有一个应用程序用django使用redis和celery进行一些异步任务。 我正在使用celery任务来执行一些存储过程。该SP从5分钟到30分钟完全执行(取决于记录的数量)。 一切都很好。 但我需要能够多次执行任务。但是现在当我运行任务而另一个用户也运行任务时,这两个任务同时执行。 我需要任务进入队列并且只在第一个任务完成时执行。 我的settings.py:
BROKER_URL = 'redis://localhost:6379/0'
CELERY_IMPORTS = ("pc.tasks", )
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_RESULT_BACKEND='djcelery.backends.cache:CacheBackend'
tasks.py
from __future__ import absolute_import
from celery.decorators import task
from celery import task, shared_task
from .models import Servicio, Proveedor, Lectura_FTP, Actualizar_Descarga
from .models import Lista_Archivos, Lista_Final, Buscar_Conci
@task
def carga_ftp():
tabla = Proc_Carga()
sp = tabla.carga()
return None
@task
def conci(idprov,pfecha):
conci = Buscar_Conci()
spconc = conci.buscarcon(idprov,pfecha)
我以这种方式在我的视图中调用任务:
conci.delay(prov,DateV);
如何创建或设置一个队列列表,并且只有在之前的抽签结束时才会执行任务
提前致谢
答案 0 :(得分:0)
你可以限制工作人员的任务,我假设你只需要一个工人,所以在调用djcelery时只需要启动一个工人。
python manage.py celery worker -B --concurrency=1
答案 1 :(得分:0)
您可以使用锁定(例如,来自我的某个项目):
def send_queued_emails(*args, **kwargs):
from mailer.models import Message
my_lock = redis.Redis().lock("send_mail")
try:
have_lock = my_lock.acquire(blocking=False)
if have_lock:
logging.info("send_mail lock ACQUIRED")
from celery import group
if Message.objects.non_deferred().all().count() > 0:
t = EmailSenderTask()
g = (group(t.s(message=msg) for msg in Message.objects.non_deferred().all()[:200]) | release_redis_lock.s(lock_name="send_mail"))
g()
else:
logging.info("send_mail lock RELEASED")
my_lock.release()
else:
logging.info("send_mail lock NOT ACQUIRED")
except redis.ResponseError as e:
logging.error("Redis throw exception : {}".format(e))
except:
my_lock.release()
logging.error("send_mail lock RELEASED because of exception")