我有个任务,有点像这样:
@task()
def async_work(info):
...
任何时候,我都可以用一些信息调用async_work。出于某种原因,我需要确保一次只运行一个异步工作,其他调用请求必须等待。
所以我提出了以下代码:
is_locked = False
@task()
def async_work(info):
while is_locked:
pass
is_locked = True
...
is_locked = False
但是它说访问局部变量是无效的。。。
怎么解决?
Tags:
您可能不想为芹菜工人使用
concurrency=1
-您希望同时处理您的任务。相反,你可以使用某种锁定机制。只需确保缓存的超时时间大于完成任务的时间。Redis公司
内存缓存
受celery documentation启发的示例
访问局部变量是无效的,因为您可以让几个芹菜工人运行任务。这些工人甚至可能在不同的主机上。因此,基本上,变量实例的数量与芹菜工人运行的数量一样多 你的任务。因此,即使你的代码不会引发任何错误,你也不会得到期望的效果。
要实现您的目标,您需要将芹菜配置为只运行一个工人。因为任何工人都可以在任何给定的时间处理单个任务,所以您可以得到所需的内容。
编辑:
根据Workers Guide > Concurrency:
因此,您需要像这样运行worker:
编辑2:
令人惊讶的是,还有另一个解决方案,而且甚至在官方文档中也有,请参阅Ensuring a task is only executed one at a time文章。
我已经实现了一个装饰器来处理这个问题。这是基于官方芹菜文件的Ensuring a task is only executed one at a time。
它使用函数名及其参数和kwargs创建一个lock_id,该id在Django的缓存层中设置/获取(我只在Memcached中测试过,但它也应该在Redis中使用)。如果已在缓存中设置了lock_id,则会将任务放回队列并退出。
然后,您可以将它作为第一个装饰器应用于任何任务:
相关问题 更多 >
编程相关推荐