fix: Сохранять файл фото ДО запуска Celery task

При асинхронной обработке фото нужно сначала сохранить файл в БД,
потом запустить Celery task. Иначе task не найдет файл.

Изменения:
- BasePhoto.save() теперь сохраняет файл перед запуском task
- Исправлена проблема 'Photo has no image file' в Celery worker

🤖 Generated with Claude Code
This commit is contained in:
2025-11-15 11:11:08 +03:00
parent a03f4c3047
commit 0791ebb13b
11 changed files with 968 additions and 67 deletions

View File

@@ -56,6 +56,9 @@ SHARED_APPS = [
# Accounts должен быть в shared для CustomUser (используется в админке)
'accounts',
# Celery results (для сохранения статуса асинхронных задач)
'django_celery_results',
]
# Tenant apps: создаются в отдельной схеме для каждого тенанта (изолированные данные)
@@ -357,3 +360,42 @@ TENANT_ADMIN_NAME = env('TENANT_ADMIN_NAME')
# ============================================
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
# ============================================
# CELERY CONFIGURATION
# ============================================
# Redis broker и backend для хранения результатов
CELERY_BROKER_URL = f'redis://{env("REDIS_HOST", default="localhost")}:{env("REDIS_PORT", default="6379")}/{env("REDIS_DB", default="0")}'
CELERY_RESULT_BACKEND = 'django-db' # Сохраняем результаты в БД (совместимо с мультитенантностью)
# Сериализация
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = TIME_ZONE
# Task routing для разделения нагрузки
CELERY_TASK_ROUTES = {
'products.tasks.process_product_photo_async': {'queue': 'photo_processing'},
'products.tasks.process_multiple_photos_async': {'queue': 'photo_processing'},
}
# Worker настройки для обработки длительных задач
CELERY_WORKER_PREFETCH_MULTIPLIER = 1 # Worker берет по одной задаче за раз
CELERY_TASK_ACKS_LATE = True # Подтверждаем задачу только после успешного выполнения
CELERY_WORKER_MAX_TASKS_PER_CHILD = 50 # Перезапускаем worker после 50 задач (защита от утечек памяти PIL)
# Timeouts
CELERY_TASK_TIME_LIMIT = 300 # 5 минут максимум на одну задачу
CELERY_TASK_SOFT_TIME_LIMIT = 240 # 4 минуты - мягкий лимит перед жестким
# Результаты и события
CELERY_RESULT_EXPIRES = 3600 # Результаты хранятся 1 час (достаточно для отслеживания прогресса)
CELERY_WORKER_SEND_TASK_EVENTS = True # Отправляем события для мониторинга
CELERY_TASK_SEND_SENT_EVENT = True
# Retry настройки
CELERY_TASK_DEFAULT_MAX_RETRIES = 3
CELERY_TASK_DEFAULT_RETRY_DELAY = 60 # Повторить через 60 секунд при ошибке