# BAT-047 Implementation - Status: completed - Batch: BAT-047 ## Plan Summary REQ-091~094 구현. 변경은 발행 경로에 국소화하고 wire 계약·consume/RPC 경로 불변 유지. 1. `rabbitmq.py` — `_connect` 타임아웃 파라미터화, `_force_reconnect` 신규, `keepalive_tick` 신규, `publish_event` 재시도 로직, `_publish_dlq` ERROR 격상. 2. `application/messaging.py` — `MessagingTransport` 포트에 `keepalive_tick()` 추가 (no-op default). 3. `adapters/messaging/in_memory.py` — `keepalive_tick()` no-op 구현. 4. `runtime/daemon.py` — `_make_event_emitter` WARNING→ERROR 격상, `_execution_loop` keepalive 틱 삽입. 5. `tests/adapters/messaging/test_publish_reliability.py` — 신규 테스트 17건. 6. `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.py` - `MessagingTransport` 프로토콜에 `keepalive_tick() -> None` 추가 - `trex_core/adapters/messaging/in_memory.py` - `InMemoryTransport.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 1. `rabbitmq.py` — `_connect`, `_force_reconnect`, `keepalive_tick`, `publish_event`, `_do_basic_publish`, `_publish_dlq` 수정/추가. 2. `application/messaging.py` — `keepalive_tick` 포트 메서드 추가. 3. `in_memory.py` — no-op 추가. 4. `daemon.py` — `_make_event_emitter` + `_execution_loop` 수정. 5. 신규 테스트 17건 작성. 6. `python3 -m pytest tests/adapters/messaging/test_publish_reliability.py -v` → **17 passed**. 7. `python3 -m pytest tests/ --ignore=...rabbitmq_transport... --ignore=...rabbitmq_intent_e2e... -q` → **554 passed, 40 skipped** (기존 537 + 신규 17, 회귀 0). 8. 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 재현은 운영 환경 배포 후 확인 필요.