我有一个相当长的运行任务,需要在插入或更新特定模型后执行。
我决定使用$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任务中使用旧属性值获取旧实例。
解决方法是在几秒钟的延迟时间内运行芹菜任务,但显然这不是一个好的解决方案,也无法保证在重负载或长网络延迟下的正确执行行为。
我是完全错误还是做了一些细微的修改我能让它发挥作用?
答案 0 :(得分:15)
这可能是由于您在事务中执行更新所致。该事务在Celery任务已经启动后提交,这导致Celery任务在运行时看到您的旧值。
您可以尝试以下更改:
- (UIView*) iconView