Single-file rescan UX + post-fork DB engine disposal (v2.6.41)#56
Merged
ttlequals0 merged 1 commit intomainfrom Apr 27, 2026
Merged
Single-file rescan UX + post-fork DB engine disposal (v2.6.41)#56ttlequals0 merged 1 commit intomainfrom
ttlequals0 merged 1 commit intomainfrom
Conversation
….41) Fix the UI flickering to "done" mid-rescan and the silent first-attempt NotImplementedError on Celery worker scans. - scan_service.scan_single_file accepts an optional scan_id and reuses the existing ScanState row when one matches. The Celery scan_media_task passes scan_id through for scan_type='single'. Eliminates the second ScanState that the UI's progress monitor lost track of. - worker_process_init signal now disposes the SQLAlchemy engine in each forked Celery worker, so post-fork libpq sockets aren't shared with the parent process. Removes the recurring PGRES_TUPLES_OK / NotImplementedError pattern in the worker logs. - scan_media_task catch-all preserves the ScanState row across retries (phase='initializing', is_active=True with a 'Retrying after error' progress message) instead of marking it failed/inactive on every attempt. - Extract the corruption-error string check into is_db_connection_corruption in pixelprobe/utils/celery_utils.py and use it at both detection sites. - Replace stringly-typed scan phase constants with SCAN_PHASES['INITIALIZING']. - Bump python-dotenv 1.0.0 -> 1.2.2 for CVE-2026-28684 (MEDIUM, symlink arbitrary file overwrite). New regression test: test_scan_single_file_reuses_existing_scan_state. All 320 tests pass; trivy clean of HIGH/CRITICAL/MEDIUM at the app layer.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
/api/scan-fileroute created aScanStaterow with its generatedscan_id, but the Celery worker'sscan_service.scan_single_filethen created a second row with a differentscan_idand tracked progress on that one. The UI's progress monitor briefly saw no active scan and reported the rescan complete before the worker started hashing.scan_single_filenow accepts an optionalscan_idand reuses the existing row;scan_media_taskpassesscan_idthrough forscan_type='single'.psycopg2.DatabaseError: error with status PGRES_TUPLES_OK and no message from the libpqon one ForkPoolWorker, surfacing as a bareNotImplementedErrorfromsqlalchemy/engine/result.py:_indexes_for_keysin a sibling worker. Fixed by disposing the SQLAlchemy engine in theworker_process_initCelery signal so each forked child builds its own connection pool. The existing log-handler setup in that signal was merged into a single_setup_worker_processhandler.scan_media_task's catch-all exception handler used to setphase='failed'andis_active=Falseon every error, including ones about to be retried. The handler now keeps the row active (phase='initializing'with aRetrying after error (attempt N/M)message) when more retries remain, only marking the scan failed once the retry budget is exhausted or the error is the known-fatalPGRES_TUPLES_OKcorruption case.python-dotenv1.0.0 -> 1.2.2 to resolve CVE-2026-28684 (MEDIUM, arbitrary file overwrite via symlink follow)./simplify: extractedis_db_connection_corruptionhelper inpixelprobe/utils/celery_utils.py(was inline at two sites intasks.py); replaced raw'initializing'phase strings withSCAN_PHASES['INITIALIZING']frompixelprobe/constants.py.Version
pixelprobe/version.py: 2.6.40 -> 2.6.41Test plan
test_scan_single_file_reuses_existing_scan_statecovers the create-new vs reuse-existing branch inscan_single_filettlequals0/pixelprobe:2.6.41built forlinux/amd64and pushedPGRES_TUPLES_OKorNotImplementedError