발행 전용 연결의 idle heartbeat 사망 후 첫 발행 유실 결함 제거. - REQ-091 발행 재시도 + 강제 재연결(_force_reconnect, is_open 불신) - REQ-092 idle keepalive(execution-loop 단일스레드 틱, process_data_events time_limit=0) - REQ-093 DLQ 가시성 + emit 실패 ERROR 경보(구조화 로그, dcy-029 재사용) - REQ-094 baseline 문서 정합(runtime-flows/operations/project-structure) 독립 opus QC PASS-WITH-NOTES → 시정 2건(ruff F401, AC-3 프로덕션 경로) 완료. 554 passed/47 skipped/회귀 0/ruff clean. NFR-1 wire 무회귀(interface-contract diff 0). BAT-047 release-candidate, REQ-091~094 Implemented. dcy-031. M2 트랙B. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
3.7 KiB
3.7 KiB
BAT-047 Implementation
- Status: completed
- Batch: BAT-047
Plan Summary
REQ-091~094 구현. 변경은 발행 경로에 국소화하고 wire 계약·consume/RPC 경로 불변 유지.
rabbitmq.py—_connect타임아웃 파라미터화,_force_reconnect신규,keepalive_tick신규,publish_event재시도 로직,_publish_dlqERROR 격상.application/messaging.py—MessagingTransport포트에keepalive_tick()추가 (no-op default).adapters/messaging/in_memory.py—keepalive_tick()no-op 구현.runtime/daemon.py—_make_event_emitterWARNING→ERROR 격상,_execution_loopkeepalive 틱 삽입.tests/adapters/messaging/test_publish_reliability.py— 신규 테스트 17건.docs/— baseline 문서 정합 (REQ-094).
Changed Files
코드
trex_core/adapters/messaging/rabbitmq.py_connect(connect_timeout=None): 파라미터화, 기본값self._timeout유지_force_reconnect(): 신규 —close()+_connect(connect_timeout=2.0)(NFR-2 5초 블록 예산)keepalive_tick(): 신규 —process_data_events(time_limit=0), 비소유 스레드 호출 시 잠재적 오남용 방어(소유 스레드에서만 호출 규칙은 daemon.py에서 보장)publish_event(): 1차 실패 시_force_reconnect+ 재시도,UnroutableError는 재시도 없이 DLQ_do_basic_publish(): 신규 내부 헬퍼 — basic_publish 로직 추출(DRY)_publish_dlq(): WARNING → ERROR 2건(DLQ 유입 + DLQ 재발행 실패)
trex_core/application/messaging.pyMessagingTransport프로토콜에keepalive_tick() -> None추가
trex_core/adapters/messaging/in_memory.pyInMemoryTransport.keepalive_tick()no-op 구현
trex_core/runtime/daemon.py_make_event_emitter: WARNING → ERROR, routing key + slot_id + strategy_id 포함_execution_loop:self.event_publisher.keepalive_tick()각 틱 시작 시 호출
테스트
tests/adapters/messaging/test_publish_reliability.py(신규, 17 테스트)
문서 (REQ-094)
docs/runtime-flows.md—슬롯 이벤트 발행/구독,데몬 lifecycle갱신docs/project-structure.md— messaging.py, rabbitmq.py 기술 갱신docs/operations.md— DLQ 가시성/경보 섹션 신규
Execution Log
rabbitmq.py—_connect,_force_reconnect,keepalive_tick,publish_event,_do_basic_publish,_publish_dlq수정/추가.application/messaging.py—keepalive_tick포트 메서드 추가.in_memory.py— no-op 추가.daemon.py—_make_event_emitter+_execution_loop수정.- 신규 테스트 17건 작성.
python3 -m pytest tests/adapters/messaging/test_publish_reliability.py -v→ 17 passed.python3 -m pytest tests/ --ignore=...rabbitmq_transport... --ignore=...rabbitmq_intent_e2e... -q→ 554 passed, 40 skipped (기존 537 + 신규 17, 회귀 0).- baseline 문서 정합 (runtime-flows, project-structure, operations).
Validation (중간)
- 신규 17건 전부 통과.
- 기존 537 passed → 554 passed (신규 17 추가). 회귀 0.
TREX_RABBITMQ_TEST_URL필요 통합 테스트 2건(test_rabbitmq_transport.py, test_rabbitmq_intent_e2e.py): 환경 없어 skip — 기존과 동일.
Remaining Risks
- R-3(Medium): at-least-once 재시도 — 중복 이벤트 발행 가능. OQ-2(orb/tsl 소비자 멱등성)는 delivery 검증으로 추적. trex-core 범위 밖.
- R-live: 실제 pika 연결 환경(TREX_RABBITMQ_TEST_URL)에서의 keepalive/재연결 동작은 통합 테스트로만 검증 가능 — CI 환경 없어 미검증. unit mock 기반으로 logic을 검증했으나 실제 broker half-open 재현은 운영 환경 배포 후 확인 필요.