feat: Improve photo processing cancellation handling in face service

This commit enhances the photo processing workflow in the FaceService by ensuring that cancellation checks occur after completing the current photo's processing, including pose detection and database commits. It introduces robust error handling during progress updates, allowing for graceful cancellation and improved user feedback. Documentation has been updated to reflect these changes, enhancing the overall user experience and reliability of the photo processing feature.
This commit is contained in:
tanyar09 2025-11-04 15:05:43 -05:00
parent e2cadf3232
commit a70637feff

View File

@ -702,6 +702,8 @@ def process_unprocessed_photos(
first_photo_start = time.time()
print(f"[FaceService] Starting first photo processing...")
# Process photo fully (including pose detection, DeepFace, and database commit)
# This ensures all data is complete before checking for cancellation
faces_detected, faces_stored = process_photo_faces(
db,
photo,
@ -718,27 +720,97 @@ def process_unprocessed_photos(
first_photo_time = time.time() - first_photo_start
print(f"[FaceService] First photo completed in {first_photo_time:.2f}s")
# Check for cancellation AFTER finishing the current photo completely
# This allows the current photo to complete (including pose detection and DB commit),
# then stops before the next one
if check_cancelled():
print(f"[FaceService] Job cancelled after finishing photo {idx}/{total}")
# Update progress to show cancellation status
if update_progress:
try:
update_progress(
idx,
total,
"Cancelled by user - finished current photo",
total_faces_detected,
total_faces_stored,
)
except KeyboardInterrupt:
# If update_progress raises KeyboardInterrupt, that's expected
# The cancellation check already happened, so we're good
pass
break
# Update progress only if NOT cancelled (to avoid unnecessary KeyboardInterrupt)
if update_progress:
update_progress(
idx,
total,
f"Completed {photo.filename} ({idx}/{total})",
total_faces_detected,
total_faces_stored,
)
try:
update_progress(
idx,
total,
f"Completed {photo.filename} ({idx}/{total})",
total_faces_detected,
total_faces_stored,
)
except KeyboardInterrupt:
# If cancellation was detected during update_progress, check again and break
if check_cancelled():
print(f"[FaceService] Job cancelled during progress update after photo {idx}/{total}")
break
# Re-raise if it wasn't a cancellation
raise
except KeyboardInterrupt:
# Cancellation was requested - stop processing gracefully
print(f"[FaceService] Job cancelled during processing of photo {idx}/{total}")
if check_cancelled():
if update_progress:
try:
update_progress(
idx,
total,
"Cancelled by user",
total_faces_detected,
total_faces_stored,
)
except KeyboardInterrupt:
pass
break
# Re-raise if it wasn't a cancellation
raise
except Exception as e:
# Log error but continue processing other photos
print(f"[FaceService] Error processing photo {photo.filename}: {e}")
import traceback
traceback.print_exc()
if update_progress:
update_progress(
idx,
total,
f"Error: {photo.filename}",
total_faces_detected,
total_faces_stored,
)
try:
update_progress(
idx,
total,
f"Error: {photo.filename}",
total_faces_detected,
total_faces_stored,
)
except KeyboardInterrupt:
# If cancellation detected during error progress update, stop
if check_cancelled():
print(f"[FaceService] Job cancelled after error on photo {idx}/{total}")
break
# Check for cancellation after handling error
if check_cancelled():
print(f"[FaceService] Job cancelled after error on photo {idx}/{total}")
if update_progress:
try:
update_progress(
idx,
total,
"Cancelled by user - finished current photo",
total_faces_detected,
total_faces_stored,
)
except KeyboardInterrupt:
pass
break
return photos_processed, total_faces_detected, total_faces_stored