Files
trex-core/docs/srs/Exception/req-023_messaging-delivery-reliability.md
T

7.9 KiB

req-023: messaging delivery 신뢰성 (effectively-once + durable + DLQ + publisher confirms)

  • Status: Implemented
  • Type: Exception
  • Priority: High
  • Owner: project maintainers

Intent

  • RabbitMQ 메시징을 도입하면서 at-least-once 재전달이 intent 중복 실행이나 슬롯 권위 불변식 위반을 일으키지 않도록, idempotency + durable + 단일 consumer FIFO + dead-letter + publisher confirms 로 effectively-once 동작을 보장한다. 진짜 exactly-once 는 추구하지 않는다.

Requirement

  • intent admission RPC 는 다음 신뢰성 규약을 따른다.
    • 메시지/큐는 durable + persistent delivery_mode.
    • correlation_id = intent 멱등키(dcy-003 패턴, {asset_id}:{order_id}:{execution_id} 또는 등가) 로 dedup.
    • 슬롯 전이를 Postgres 에 durable commit 한 뒤 ack(manual ack). 재전달 시 dedup 게이트가 단일 실행을 보장한다.
    • 단일 consumer + prefetch=1 로 FIFO 순서 보존(trex-core 단일 writer 불변식 A 와 정합).
  • 스냅샷 RPC 는 read-only 멱등이므로 at-least-once + transient 큐/메시지 + manual ack 로 운영하고 별도 dedup 을 강제하지 않는다.
  • 이벤트 pub/sub 는 다음 신뢰성 규약을 따른다.
    • trex.events 는 durable topic exchange.
    • 전략별 queue 는 durable + per-strategy 로 down 중 catch-up 가능. 무한 적체 방지를 위해 TTL 또는 max-length 정책을 적용하고 초과분은 drop-oldest 후 스냅샷 RPC 로 reconcile.
    • 이벤트 페이로드는 delta 가 아니라 현재 상태 + 단조 증가 시퀀스(슬롯 version/timestamp) 를 운반해 last-wins 가 성립하도록 한다(순서 보증 불요).
    • 발행은 publisher confirms 로 broker 수락을 확인하고, 발행 실패/거부는 dead-letter 경로로 격리한다.
  • 미수신/중복 이벤트 보정은 권위 reconcile 경로인 스냅샷 RPC 가 담당한다(이벤트는 push 최적화이지 단일 진실원이 아님).

Acceptance Criteria

  1. Given 동일 correlation_id 의 intent 메시지가 2회 전달, When intent consumer 가 처리, Then 슬롯 전이는 1회만 일어나고 두 번째는 dedup 으로 무시된다(NFR-2).
  2. Given intent consumer 가 슬롯 transition 후 ack 직전 크래시 상황을 시뮬레이션, When 재기동 후 동일 메시지가 재전달, Then 멱등 dedup 으로 슬롯이 추가 전이되지 않고 결국 ack 된다(durable commit + ack 순서).
  3. Given intent 큐, When 토폴로지를 검사, Then 큐와 메시지가 durable/persistent 이고 consumer 가 단일 + prefetch=1 로 선언되어 있다.
  4. Given 전략 queue 가 down 인 상태에서 trex-core 가 이벤트를 발행, When 전략이 복구되어 queue 를 다시 소비, Then 적체된 이벤트를 catch-up 으로 수신한다(durable per-strategy queue).
  5. Given 이벤트 페이로드, When 형식을 검사, Then current state + 단조 시퀀스 필드가 포함되어 last-wins 적용이 가능하다.
  6. Given trex-core 가 이벤트를 발행, When broker 가 거부/확인 실패, Then publisher confirms 가 실패를 감지하고 메시지를 dead-letter 경로로 격리한다.
  7. Given TTL 또는 max-length 가 설정된 이벤트 queue, When 한도를 초과, Then 초과 메시지는 drop-oldest 로 제거되고 후속 스냅샷 RPC reconcile 로 누락이 보정된다.

Impacted Area

  • Docs: docs/runtime-flows.md(신뢰성/dedup/ack/DLQ 흐름), docs/interface-contract.md(메시지 속성/큐 옵션) — REQ-026 에서 정합.
  • Modules: REQ-022 의 어댑터/consumer 에 ack 시점·dedup 게이트·publisher confirms·DLQ 라우팅을 통합. dedup 게이트는 dcy-003 의 멱등 store 재사용.
  • Tests: 중복 intent 메시지 dedup, crash-after-commit-before-ack 재처리, durable queue + prefetch=1 토폴로지 검사, per-strategy queue catch-up, 이벤트 페이로드 모양, publisher confirms 실패 DLQ, TTL/max-length drop-oldest + reconcile.

Notes

  • 출처: dcy-006 FR-4, NFR-2, OQ-3, R-2.
  • NFR-2(effectively-once) 는 별도 REQ 로 승격하지 않고 본 REQ AC-1/AC-2 로 흡수한다.
  • 진짜 exactly-once 는 추구하지 않는다(분산 메시징 일반 원칙). 멱등 + 권위 reconcile 로 실제 효과를 낸다.
  • DLQ 라우팅 키/큐 이름 같은 세부 규약은 batch design 에서 확정한다(본 REQ 는 정책 수준).

Change Log

CHG-20260605-01

  • Date: 2026-06-05
  • Author: Justin Ko

Change Summary

  • dcy-006 FR-4 로부터 최초 생성(Proposed). NFR-2(effectively-once) 흡수.

Intent

  • messaging delivery 신뢰성(intent dedup, durable+FIFO, 이벤트 catch-up, publisher confirms, DLQ, TTL/max-length) backlog 정규화.

Acceptance Criteria Delta

  • Added:
    • 중복 intent dedup, crash-after-commit-before-ack 재처리, durable+prefetch=1 토폴로지, per-strategy queue catch-up, 이벤트 페이로드 모양, publisher confirms DLQ, TTL/max-length drop-oldest (총 7개 기준)
  • Updated:
    • 없음
  • Removed:
    • 없음

Impacted Area Delta

  • Docs:
    • docs/runtime-flows.md, docs/interface-contract.md
  • Modules:
    • adapters/messaging consumer/publisher 의 ack/dedup/DLQ/confirms 통합
  • Tests:
    • 신뢰성 7가지 시나리오

Delivery Trace Delta

  • Batches:
    • none
  • Releases:
    • none

Revalidation Impact

  • Reverification Needed: no
  • Existing Implementation Invalidated: no
  • Status Recommendation: keep-current
  • Follow-up Action: confirm-req 후 batch 편성

Validation Plan

  • stub/RabbitMQ 어댑터로 dedup/durable/catch-up/confirms/DLQ/TTL 시나리오를 검증.

CHG-20260605-02

  • Date: 2026-06-05
  • Author: Justin Ko

Change Summary

  • Status 변경: Proposed -> Approved. confirm-req 승인 게이트 통과.

Intent

  • messaging delivery 신뢰성(effectively-once + durable + DLQ + publisher confirms) 요구사항을 delivery input 으로 승인.

Acceptance Criteria Delta

  • Added/Updated/Removed: 없음

Impacted Area Delta

  • Docs/Modules/Tests: 없음

Delivery Trace Delta

  • Batches:
    • none
  • Releases:
    • none

Revalidation Impact

  • Reverification Needed: no
  • Existing Implementation Invalidated: no
  • Status Recommendation: Approved
  • Follow-up Action: REQ-021/022/025 와 함께 batch 편성

Validation Plan

  • 기존 Acceptance Criteria 로 batch delivery 에서 검증.

CHG-20260605-03

  • Date: 2026-06-05
  • Author: Justin Ko

Change Summary

  • Status 변경: Approved -> Implemented. BAT-007 release-candidate verification evidence 기반.

Intent

  • messaging delivery 신뢰성(effectively-once + durable + DLQ + publisher confirms + TTL/max-length)을 구현 완료 상태로 동기화.

Acceptance Criteria Delta

  • Added/Updated/Removed: 없음

Impacted Area Delta

  • Docs/Modules/Tests: 없음

Delivery Trace Delta

  • Batches:
    • BAT-007 (release-candidate)
  • Releases:
    • none

Revalidation Impact

  • Reverification Needed: no
  • Existing Implementation Invalidated: no
  • Status Recommendation: Implemented
  • Follow-up Action: release 단계는 별도 진행

Validation Plan

  • AC-1: tests/application/test_messaging_intent_consumer.py::test_duplicate_correlation_id_dedups_via_intent_log + tests/adapters/messaging/test_rabbitmq_intent_e2e.py::test_intent_admission_rpc_dedups_duplicate_correlation_id_over_rabbitmq (실 RabbitMQ).
  • AC-2: ack-after-handler 코드(Daemon._intent_rpc_loop) + dedup 테스트가 ack 순서 전제 통과.
  • AC-3: tests/adapters/messaging/test_rabbitmq_intent_e2e.py::test_intent_queue_topology_uses_dlq_pointer.
  • AC-4: topology.STRATEGY_QUEUE_ARGS + per-strategy filter 테스트.
  • AC-5: tests/application/test_messaging_event_publisher.py::test_fill_emits_slot_filled_event_with_routing_key_and_state.
  • AC-6: RabbitMQTransport._publish_dlq + handler exception NACK + tests/adapters/messaging/test_in_memory_transport.py::test_publish_event_with_no_subscriber_routes_to_dlq.
  • AC-7: tests/adapters/messaging/test_topology.py::test_strategy_queue_args_have_ttl_and_max_length.