Нужно исправить DRF-обработчик, передавать задаче идентификатор Feedback и согласовать enqueue с commit. Письмо и изменение БД не образуют общую транзакцию, поэтому возможны потери статуса или дубли писем.
Асинхронное изменение статуса в Django
Нужно исправить DRF-обработчик, передавать задаче идентификатор Feedback и согласовать enqueue с commit. Письмо и изменение БД не образуют общую транзакцию, поэтому возможны потери статуса или дубли писем.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Провести ревью кода. Оценить корректность и надёжность реализованной логики.
@app.task(name='change_status_feedback')
def change_status_feedback(feedback):
feedback.status = 'in_progress'
send_mail()
feedback.save()
class CreateFeedbackAPIView(APIView):
def create(self, request):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
feedback = Feedback.objects.create(**serializer.validated_data)
change_status_feedback.delay(feedback)
return feedback
Ответ
Нужно исправить DRF-обработчик, передавать задаче идентификатор Feedback и согласовать enqueue с commit. Письмо и изменение БД не образуют общую транзакцию, поэтому возможны потери статуса или дубли писем.
APIView обрабатывает post, не create, и не имеет get_serializer без GenericAPIView. Верните Response с сериализованной записью, а задачу вызывайте после успешного commit с feedback.pk.
Worker заново читает объект и проверяет допустимость перехода. Сначала зафиксируйте состояние обработки, затем отправляйте письмо и отмечайте результат. Даже такой порядок требует идемпотентности: worker может упасть после внешнего эффекта. Для надёжности используют outbox и повторяемую доставку. Стандартный send_mail требует аргументы и может выбросить исключение; голый вызов не является полноценной реализацией.