fix: используем transaction.on_commit для Celery задач

Исправлена проблема race condition когда Celery задача process_message_notifications
запускалась до завершения транзакции БД, что приводило к ошибке 'message_not_found'.

Теперь задача запускается только после успешного commit, гарантируя что объект
уже доступен в базе данных для worker процесса.
This commit is contained in:
Игорь Надеин 2026-01-09 11:09:58 +03:00
parent a84e253d2c
commit e2f1362813

View File

@ -9,6 +9,7 @@ Signals для автоматической генерации уведомле
"""
import re
from django.db import transaction
from django.db.models.signals import post_save, m2m_changed
from django.dispatch import receiver
from django.contrib.auth import get_user_model
@ -88,20 +89,21 @@ def create_message_notifications(sender, instance, created, **kwargs):
# Signal handler сразу возвращает управление
from notifications.tasks import process_message_notifications_task
try:
# Запускаем асинхронно через Celery
process_message_notifications_task.delay(instance.id)
except Exception as e:
# Если Celery недоступен - fallback на синхронную обработку
import logging
logger = logging.getLogger(__name__)
logger.warning(f"Celery unavailable, using sync fallback: {e}")
_create_message_notifications_sync(instance)
except Exception as e:
# Если что-то пошло не так, логируем но не ломаем сохранение сообщения
import logging
logger = logging.getLogger(__name__)
logger.error(f"Failed to queue message notifications: {e}", exc_info=True)
def send_task():
"""Отложенная отправка задачи после commit транзакции"""
try:
# Запускаем асинхронно через Celery
process_message_notifications_task.delay(instance.id)
except Exception as e:
# Если Celery недоступен - fallback на синхронную обработку
import logging
logger = logging.getLogger(__name__)
logger.warning(f"Celery unavailable, using sync fallback: {e}")
_create_message_notifications_sync(instance)
# ВАЖНО: Запускаем задачу только после commit транзакции
# Иначе Celery worker не найдет объект в БД (race condition)
transaction.on_commit(send_task)
def _create_message_notifications_sync(instance):