芹菜,一个一个队列,并列许多时间排队

时间:2011-12-15 23:44:03

标签: python rabbitmq celery

我正在尝试使用芹菜来管理任务。 我现在遇到的问题是,我有许多小任务(电子邮件,跨服务器帖子等) 和时间消耗的任务,如文件上传。

有没有办法指明上传将始终是一个接一个。只有一个任务及时执行,而其他工作人员将在其他队列上工作?

2 个答案:

答案 0 :(得分:0)

序列化任务执行的有效方法是使用互斥(互斥)。

Python的threading模块有a Lock object,可以是used to this effect

# ...
module_lock = threading.Lock() # or make this an attribute in an object with sufficiently-large scope
# ...
def do_interesting_task():
     with module_lock.acquire():
         interesting_task()
  

“放弃所有希望,你们进入这里。”

互斥量和信号量是强大的工具,但不明智地使用它们会产生死锁并偶尔吃掉你的午餐。

答案 1 :(得分:0)

与此同时,我已经实施了这样的解决方案,效果非常好。 但是,我不太确定,tha max_retries = None表示将有无限次重试。 此解决方案适用于redis,但可以在支持增量的原子操作的任何其他引擎上工作。

@task(max_retries=None,default_retry_delay=3)
def sleepTask():
    if r.incr('sleep_working')>1:
        r.incr('sleep_working',-1)
        sleepTask.retry()
    else:
        try:
            r.expire('sleep_working',3600)
            sleep(30)
        finally:
            r.incr('sleep_working',-1)
        return True

这里的关键是,incr是原子的,所以它永远不会发生,两个客户端接收计数器== 1.

同样过期是非常重要的,任何事情都可能发生,我们将永远得到我们的计数器> 1,所以过期确保,无论如何,在特定的时间计数器将被删除。该值可根据需要进行调整。我的上传大文件,所以3600听起来不错。

我认为这是一个很好的起点,通过接收redis_key和expire_time值来制作自定义Task对象,它将自动完成所有这些操作。如果我要做这样的任务,我会更新这篇文章。

作为奖励,此解决方案也可轻松调整为2/3 /任何其他数量的并行限制,方法是将> 1更改为> anynumber