Problem
R3x::ChangeDetectionJob currently reads trigger state, runs detect_changes, enqueues a workflow, and writes the updated state without any explicit row-level locking or idempotency guard. That works only as long as queue writes and app writes share the same database transaction semantics.
Why this matters
- Two workers can process the same trigger at the same time and both enqueue the same workflow.
- A future queue/backend split would weaken the current atomicity assumptions.
- Duplicate runs or cursor skew are hard to diagnose after the fact.
Suggested direction
- Lock the trigger state record during the detect/update path.
- Make enqueue decisions idempotent where possible.
- Add tests that simulate overlapping jobs and verify only one run is enqueued.
- Revisit the transaction boundary so correctness does not depend on Solid Queue sharing the app database forever.
Files to inspect
app/jobs/r3x/change_detection_job.rb
app/models/r3x/trigger_state.rb
test/jobs/r3x/change_detection_job_test.rb
Problem
R3x::ChangeDetectionJobcurrently reads trigger state, runsdetect_changes, enqueues a workflow, and writes the updated state without any explicit row-level locking or idempotency guard. That works only as long as queue writes and app writes share the same database transaction semantics.Why this matters
Suggested direction
Files to inspect
app/jobs/r3x/change_detection_job.rbapp/models/r3x/trigger_state.rbtest/jobs/r3x/change_detection_job_test.rb