芹菜:任务单身人士?

时间:2012-08-11 04:16:28

标签: singleton task communication celery

我有一项任务需要从触发它的网页异步运行。这个任务运行的时间相当长,而且由于网页可能会收到很多这些请求,我希望celery只能在给定时间运行这个任务的一个实例。

我有什么方法可以在Celery本地做到这一点?我很想创建一个数据库表来保存这个状态,以便与之通信的所有任务,但它感觉很hacky。

2 个答案:

答案 0 :(得分:2)

您可以为使用CELERYD_CONCURRENCY = 1配置的任务创建专用工作程序,然后该工作程序上的所有任务将同步运行

答案 1 :(得分:1)

您可以使用memcache / redis。 芹菜官方网站上有一个例子 - http://docs.celeryproject.org/en/latest/tutorials/task-cookbook.html

如果您更喜欢redis(这是一个Django实现,但您也可以根据需要轻松修改它):

from django.core.cache import cache
from celery.utils.log import get_task_logger


logger = get_task_logger(__name__)


class SingletonTask(Task):
    def __call__(self, *args, **kwargs):
        lock = cache.lock(self.name)

        if not lock.acquire(blocking=False):
            logger.info("{} failed to lock".format(self.name))
            return

        try:
            super(SingletonTask, self).__call__(*args, **kwargs)
        except Exception as e:
            lock.release()
            raise e
        lock.release()

然后将其用作基本任务:

@shared_task(base=SingletonTask)
def test_task():
    from time import sleep
    sleep(10)

这种实现是无阻塞的。如果您希望下一个任务等待上一个任务更改blocking=False更改为blocking=True并添加timeout