Исправлена гонка БД при async обработке первого фото комплекта
- Добавлен retry на 5 сек при DoesNotExist для ожидания коммита транзакции - temp_path сохраняется в PhotoProcessingStatus.result_data при постановке задачи - При окончательной неудаче not_found удаляется осиротевший temp файл - Предотвращает накопление temp файлов при гонке создания фото
This commit is contained in:
@@ -102,7 +102,8 @@ class BasePhoto(models.Model):
|
|||||||
photo_id=self.pk,
|
photo_id=self.pk,
|
||||||
photo_model=photo_model_class,
|
photo_model=photo_model_class,
|
||||||
status='pending',
|
status='pending',
|
||||||
task_id=task_result.id
|
task_id=task_result.id,
|
||||||
|
result_data={'temp_path': getattr(temp_image, 'name', None)}
|
||||||
)
|
)
|
||||||
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
|||||||
@@ -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}")
|
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:
|
except Exception as exc:
|
||||||
logger.error(f"[Celery] Error processing photo {photo_id} in {schema_name}: {str(exc)}",
|
logger.error(f"[Celery] Error processing photo {photo_id} in {schema_name}: {str(exc)}",
|
||||||
|
|||||||
Reference in New Issue
Block a user