在芹菜中处理`post_save`信号

时间:2017-07-24 09:23:46

标签: django celery django-signals

我有一个相当长的运行任务,需要在插入或更新特定模型后执行。

我决定使用$this->serviceLocator->get('config);信号而不是覆盖post_save方法来减少耦合。由于Django信号不是异步的,我不得不做长期运行的工作作为Celery任务(我们已经在我们的堆栈中)。

我的信号处理功能的简化版本如下:

save

另外,因为作业是异步完成的,所以我传递了对象的主键而不是实例本身。

@receiver(post_save, sender=MyModel)
def my_model_post_save(sender, instance, **kwargs):
    handle_save_task.apply_async(args=(instance.pk,))

实际问题是当执行芹菜任务时,它无法访问新保存的实例。就像它在保存之前执行一样! (这不是被称为 post _ 保存的信号吗?真是讽刺)

通过“保存前执行”我的意思是如果它是一个插入到DB的新实例,在芹菜任务中我得到@app.task(queue='elastic') def handle_save_task(instance_pk): try: instance = MyModel.objects.get(pk=instance_pk) except ObjectDoesNotExist: # Abort logger.warning("Saved object was deleted before this task get a chance to be executed [id = %d]" % instance_pk) else: # Do my things with instance 异常,并且在实例已经在DB中且保存方法是调用以更新其某些属性我在celery任务中使用旧属性值获取旧实例。

解决方法是在几秒钟的延迟时间内运行芹菜任务,但显然这不是一个好的解决方案,也无法保证在重负载或长网络延迟下的正确执行行为。

我是完全错误还是做了一些细微的修改我能让它发挥作用?

1 个答案:

答案 0 :(得分:15)

这可能是由于您在事务中执行更新所致。该事务在Celery任务已经启动后提交,这导致Celery任务在运行时看到您的旧值。

您可以尝试以下更改:

- (UIView*) iconView