【发布时间】:2013-04-12 22:50:24
【问题描述】:
我想向 Celery 中长时间运行的任务发送“暂停”信号,我正在尝试找出最好的方法。在视图中,我可以从数据库中提取对象的一个实例并告诉它保存,但它与 Celery 中的对象实例不同。该对象不会检查它是否已暂停。
从长期运行的类和任务中轮询数据库感觉很奇怪且不切实际,因此我正在考虑向我的实例发送消息。我看过使用 pubsub,但我更喜欢使用 Django 信号,因为它已经是一个 Django 项目。我可能以错误的方式处理这个问题。
这是一个不起作用的例子:
模型.py
class LongRunningClass(models.Model):
is_paused = models.BooleanField(default=False)
processed_files = models.IntegerField(default=0)
total_files = models.IntegerField(default=100)
def long_task(self):
remaining_files = self.total_files - self.processed_files
for i in xrange(remaining_files):
if not self.is_paused:
self.processed_files += 1
time.sleep(1)
# Task complete, let's save.
self.save()
Views.py
def pause_task(self, pk):
lrc = LongRunningClass.objects.get(pk=pk)
lrc.is_paused = True
lrc.save()
return HttpResponse(json.dumps({'is_paused': lrc.is_paused}))
def resume_task(self, pk):
lrc = LongRunningClass.objects.get(pk=pk)
lrc.is_paused = False
lrc.save()
# Pretend this is a Celery task
lrc.long_task()
因此,如果我修改 models.py 以使用信号,我可以添加这些行,但它仍然无法正常工作:
pause_signal = django.dispatch.Signal(providing_args=['is_paused'])
@django.dispatch.receiver(pause_signal)
def pause_callback(sender, **kwargs):
if 'is_paused' in kwargs:
sender.is_paused = kwargs['is_paused']
sender.save()
这也不影响已经在运行的实例化类。如何让在任务中运行的模型实例暂停?
【问题讨论】:
-
我从未使用过 celery,但我注意到在您的示例中设置
is_paused只会导致任务错误地完成(它会循环而不做任何工作)。要暂停执行,它必须是一个阻塞调用...... -
我更新了我的示例,以更好地说明“暂停”的工作原理。
标签: python django signals celery