Skip to content

fix: commit multi-step CRUD workflows atomically - #714

Open
frgfm wants to merge 2 commits into
mainfrom
codex/atomic-crud-workflows
Open

frgfm wants to merge 2 commits into
mainfrom
codex/atomic-crud-workflows

Conversation

@frgfm

@frgfm frgfm commented Oct 10, 2026 •

Copy link
Copy Markdown
Member

Prevent partial detection and alert edits by deferring workflow commits. Reuse shared save logic and unlink detections in bulk.

Workload Median latency, ms (base → PR) Peak RSS, MiB (base → PR)
Matched-frame ingestion 30.7 → 20.9 163.5 → 163.6
Delete sequence with 1,000 detections 4,589.5 → 27.6 164.3 → 163.2

Local PostgreSQL; three fresh workers/revision, one warmup then three serial requests each. Latency is request p50; RSS is median worker VmHWM including startup. CRUD memory use is essentially unchanged.

Media uploads are excluded from timing and remain outside the DB transaction. Rollback tests, Ruff and Ty pass.

Comment thread src/tests/test_crud_transactions.py Fixed
@codecov

codecov Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.00000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.73%. Comparing base (9f4c75f) to head (cf9a8f7).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
src/app/api/api_v1/endpoints/alerts.py 75.00% 1 Missing ⚠️
src/app/crud/crud_sequence.py 83.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #714      +/-   ##
==========================================
+ Coverage   94.48%   94.73%   +0.25%     
==========================================
  Files          59       59              
  Lines        3246     3250       +4     
==========================================
+ Hits         3067     3079      +12     
+ Misses        179      171       -8     
Flag Coverage Δ
backend 94.89% <96.00%> (+0.26%) ⬆️
client 91.30% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@frgfm
frgfm requested a review from MateoLostanlen October 15, 2026 12:47

@MateoLostanlen MateoLostanlen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One commit per request is the right move and the rollback tests show it works. One blocker, one small nit.

Blocker: two requests for the same pose can block each other

With commit=False, the lock on a sequence row is now kept until the end of create_detection. If one frame touches sequence A then B, and another frame of the same pose touches B then A at the same time, Postgres kills one of them with deadlock detected. That request fails with a 500 and its image is already on S3. Rare, but new with this PR: the old code released the lock right after each update.

Easy fix: lock the pose for the whole transaction before the first write, e.g. SELECT pg_advisory_xact_lock(:pose_id). Requests for the same pose then wait for each other, and the lock goes away on commit or rollback.

Nit: bump_max_conf and enqueue_validation are now always called with commit=False. The default branch is the line Codecov flags. The flag can go.

Everything else looks good: each path ends with one commit or rolls back when the session closes, skipping refresh is safe with expire_on_commit=False, the bulk UPDATE in delete_sequence does the same thing as before, and I found no lock problem with the validation worker.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants