django - Django post_save 信号和 celery 任务之间可能存在的竞争条件

标签 django django-models celery celery-task

在一个 django 2.0 应用程序中,我有一个名为 Document 的模型,它可以将图像上传并保存到文件系统。那部分有效。我正在使用 https://github.com/ageitgey/face_recognition 对图像进行一些面部识别在 celery (v 4.2.1) 任务中。我将图像的 document_id 传递给 celery 任务,因此面部识别任务可以找到要处理的图像。如果我在保存图像后从 DocumentAdmin 操作手动调用 face_recognition 任务,这一切都很好。

我尝试从 (models.signals.post_save, sender=Document) 调用 face_recognition 任务我的models.py中的方法,我在face_recognition的celery任务中从这一行得到一个错误:

document = Document.objects.get(document_id=document_id)

错误是:
[2018-11-26 16:54:28,594: ERROR/ForkPoolWorker-1] Task biometric_identification.tasks.find_faces_task[428ca39b-aefb-4174-9906-ff2146fd6f14] raised unexpected: DoesNotExist('Document matching query does not exist.',)
Traceback (most recent call last):
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/celery/app/trace.py", line 382, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/celery/app/trace.py", line 641, in __protected_call__
    return self.run(*args, **kwargs)
  File "/home/mark/python-projects/memorabilia-JSON/biometric_identification/tasks.py", line 42, in find_faces_task
    document = Document.objects.get(document_id=document_id)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/db/models/manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/db/models/query.py", line 403, in get
    self.model._meta.object_name
memorabilia.models.DoesNotExist: Document matching query does not exist.

此外,此错误并非一直发生,只是偶尔发生。其余时间,该过程有效;即图像被保存并且面部被识别。

我在 DocumentAdmin 类中覆盖了 save_model,但这只是将图像的一些元数据保存在另一个模型中。最后一行是对 super().save_model(request, obj, form, change) 的调用。 ,所以我假设 post_save 信号在那之后被调用。

在我看来,将模型保存到数据库和 celery 任务查询数据库以获取新创建的 document_id 之间存在竞争条件。我认为在保存模型之前没有激活 post_save 信号?

我是否必须在 celery 任务 face_recognition 中添加一些人为延迟才能解决这种可能的竞争条件,还是我错过了其他东西?

谢谢!

标记

最佳答案

检查您的功能,Document模型已保存。它被包裹在 atomic阻止某处或您有ATOMIC_REQUESTS设置为 True .所以当post_save被调用,事务还没有提交。所以你的模型在那一刻并没有真正保存到数据库中。

关于django - Django post_save 信号和 celery 任务之间可能存在的竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53503460/

相关文章:

python - celery 任务路线没有按预期工作

django 模型 : objects. all().delete() 没有

python - celery:通过任务id获取函数名称?

python - php memcached 和 django memcached 存储不同吗?

python - 用于加载 Angular 模板的 Django Angular 文件夹结构

python - MVC 和 Django 基础知识

django - 模型 Django 中的 ID 字段

python - 如何从 Ruby 提交 Celery 任务

python - 如何使用 tox 添加到 $PATH?

python - 无法通过django中定义的url获取对象