Исправлена гонка БД при async обработке первого фото комплекта

- Добавлен retry на 5 сек при DoesNotExist для ожидания коммита транзакции
- temp_path сохраняется в PhotoProcessingStatus.result_data при постановке задачи
- При окончательной неудаче not_found удаляется осиротевший temp файл
- Предотвращает накопление temp файлов при гонке создания фото
This commit is contained in:
2025-11-16 02:02:15 +03:00
parent 6cb2123a82
commit 509561fdb3
2 changed files with 21 additions and 3 deletions

View File

@@ -101,9 +101,26 @@ def process_product_photo_async(self, photo_id, photo_model_class, schema_name):
}
}
except PhotoModel.DoesNotExist:
except PhotoModel.DoesNotExist as e:
logger.error(f"[Celery] Photo {photo_id} not found in schema {schema_name}")
return {'status': 'error', 'reason': 'not_found', 'photo_id': photo_id}
# Retry briefly to allow DB transaction to commit (race condition on first photo)
try:
raise self.retry(exc=e, countdown=5)
except self.MaxRetriesExceededError:
# Final failure: attempt to delete the orphan temp file if we recorded it
try:
from .models.photos import PhotoProcessingStatus
status = (PhotoProcessingStatus.objects
.filter(photo_id=photo_id, photo_model=photo_model_class)
.order_by('-created_at')
.first())
temp_path = (status.result_data or {}).get('temp_path') if status else None
if temp_path and default_storage.exists(temp_path):
default_storage.delete(temp_path)
logger.info(f"[Celery] Deleted temp file (not_found): {temp_path}")
except Exception as del_exc:
logger.warning(f"[Celery] Could not delete temp file for photo {photo_id} on not_found: {del_exc}")
return {'status': 'error', 'reason': 'not_found', 'photo_id': photo_id}
except Exception as exc:
logger.error(f"[Celery] Error processing photo {photo_id} in {schema_name}: {str(exc)}",