CaptureRepository#update — InnoDB row-lock timeout
Fix Plan: CapturesController#update Lock Wait Timeout — 비동기 Worker 분리
Background#
state_machines-activerecord gem은 after_transition 콜백을 트랜잭션 내부에서 실행한다. Editing의 상태 전환 시 FORCE_APPLY_ENTITIES_STATUSES 콜백에서 N개 editing_entities를 순회하며 각 Capture row에 exclusive lock을 획득하므로, entity가 많을수록 lock 보유 시간이 선형 증가하여 동시 요청에 lock wait timeout(50s)을 유발한다. 이 heavy operation만 Sidekiq Worker로 분리하여 트랜잭션 내 lock 보유 시간을 최소화한다.
Changes#
tesla: app/workers/apply_entities_state_worker.rb (NEW)#
- What:
ApplyEntitiesStateWorkerSidekiq worker 신규 생성.editing_id와state인자를 받아, editing의 untrashed editing_entities를 순회하며#{state}_state!호출. - Why: FORCE_APPLY_ENTITIES_STATUSES 콜백의 N개 entity cascading state transition을 트랜잭션 외부(비동기)로 분리하여 lock 보유 시간 최소화.
- Lines: 전체 (신규 파일)
tesla: app/models/concerns/statable/editing.rb#
- What:
after_transition from: any, to: FORCE_APPLY_ENTITIES_STATUSES콜백 본문을ApplyEntitiesStateWorker.perform_async(model.id, transition.to_name.to_s)로 교체. - Why: 기존 inline 순회(N개 entity × save!)를 비동기 Worker 호출 1회로 변경하여 트랜잭션 내 lock 보유 시간 O(N) → O(1)로 감소.
- Lines: 141-146
Acceptance Criteria#
-
app/workers/apply_entities_state_worker.rb파일이 존재하고ApplyEntitiesStateWorker클래스를 정의 - Worker가
include Sidekiq::Worker,sidekiq_options queue: :default, retry: 3설정 포함 - Worker의
perform(editing_id, state)메서드에 nil guard (find_by+ return if nil) 포함 -
statable/editing.rbline 141-146의 콜백 본문이ApplyEntitiesStateWorker.perform_async(model.id, transition.to_name.to_s)호출로 변경 - 기존 inline each 순회 코드가 제거됨
-
ruby -c문법 검증 통과 (두 파일 모두)
Tests#
- 기존 테스트: spec 파일이 존재할 경우
bundle exec rspec spec/workers/apply_entities_state_worker_spec.rb(agent env에서는ruby -c로 대체) - 신규 테스트: 없음 (agent env 제약)