Como @dotz mencionou , dificilmente é útil gerar uma tarefa assíncrona e bloquear imediatamente e continuar esperando até que ela termine.
Além disso, se você anexar a ele dessa maneira (o
.get()
no final), você pode ter certeza de que o mymodel
as alterações de instância feitas não serão vistas pelo seu trabalhador porque ainda não serão confirmadas - lembre-se de que você ainda está dentro do atomic
quadra. O que você pode fazer em vez disso (a partir do Django 1.9) é atrasar a tarefa até que a transação ativa atual seja confirmada, usando
django.db.transaction.on_commit
gancho:from django.db import transaction
with transaction.atomic():
mymodel.save()
transaction.on_commit(lambda:
mytask.delay(mymodel.id))
Eu uso esse padrão com bastante frequência no meu
post_save
manipuladores de sinal que acionam algum processamento de novas instâncias de modelo. Por exemplo:from django.db import transaction
from django.db.models.signals import post_save
from django.dispatch import receiver
from . import models # Your models defining some Order model
from . import tasks # Your tasks defining a routine to process new instances
@receiver(post_save, sender=models.Order)
def new_order_callback(sender, instance, created, **kwargs):
""" Automatically triggers processing of a new Order. """
if created:
transaction.on_commit(lambda:
tasks.process_new_order.delay(instance.pk))
Dessa forma, no entanto, sua tarefa não será executada se a transação do banco de dados falhar. Geralmente é o comportamento desejado, mas mantenha-o em mente.
Editar :Na verdade, é melhor registrar a tarefa de aipo on_commit dessa maneira (sem lambda):
transaction.on_commit(tasks.process_new_order.s(instance.pk).delay)