Files
trex-core/docs/batches/bat-013_20260607_multi-instance-topology/design.md
T
genichinandClaude Opus 4.8 9f83c64a40 feat(multi-instance): dcy-009 BAT-013 — RabbitMQ 다중 인스턴스 토폴로지 (REQ-048~051)
dcy-009(다중 인스턴스 RabbitMQ 토폴로지) 전체 SDLC: draft-req → confirm-req →
draft-batch(BAT-013) → run-batch-delivery → confirm-req-implemented.

- REQ-048 (Configuration): DaemonInstanceConfig.from_toml + DaemonConfig.from_config
  (env 병합, portfolio_hub_token 주입) + 데몬 --config 필수 argparse + .gitignore 인스턴스
  TOML + config/instance.example.toml
- REQ-049 (Interface): topology 동적 큐명 빌더 intent/snapshot/control_queue(instance_key)
  — default=리터럴 큐명(하위호환), named=`{base}.{instance_key}` + daemon per-instance 구독
- REQ-050 (Integration): trex.direct(topic)/trex.broadcast(fanout) exchange +
  declare_topology(instance_key) per-instance binding + control dual binding + direct_routing_key
- REQ-051 (Documentation): interface-contract/runtime-flows/project-structure 정합

하위호환: instance_key="default" → 기존 리터럴 큐명·RPC 경로 무회귀(FR-5).
split-brain 방지(NFR-3): 인스턴스 전용 큐. 민감값(NFR-4): TOML + gitignore.

검증: 신규 9 단위 + RabbitMQ 라우팅 2, 단위 271 passed,
인프라 게이트 301 passed(directed 격리 S-2 + broadcast dual S-3 + default 무회귀 S-4),
ruff clean. REQ-048~051 Implemented, BAT-013 release-candidate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 15:10:36 +09:00

4.4 KiB

BAT-013 Design

  • Status: confirmed
  • Batch: BAT-013

Architecture Summary

다중 인스턴스가 동일 RabbitMQ 에서 split-brain 없이 운영되도록 토폴로지·설정을 인스턴스화한다.

  1. 동적 큐명(topology.py): intent_queue/snapshot_queue/control_queue(instance_key). instance_key in (None,"default") → 기존 리터럴(trex.intent.req 등), 그 외 → {base}.{instance_key}. 기존 상수는 default 값으로 보존(하위호환).
  2. exchange(topology.py+rabbitmq.py): trex.direct(topic,durable) + trex.broadcast(fanout,durable). declare_topology(instance_key) 가 인스턴스 큐를 direct 에 {instance_key}.{intent|control|snapshot} 로 바인딩 + control 큐를 broadcast 에 dual 바인딩.
  3. 설정(config.py): DaemonInstanceConfig(instance_key, portfolio_hub_token) + from_toml(path)(tomllib) + DaemonConfig.from_config(toml_path) 가 from_env() 결과에 TOML 을 병합(portfolio_hub_token → PortfolioHubConfig.token).
  4. 진입점(daemon.main): argparse --config 필수. instance_key 를 declare/consume 에 일관 전달.

Changed Areas

  • Docs: interface-contract.md(routing key)·runtime-flows.md(TOML 기동/라우팅)·project-structure.md(동적 큐명/설정/exchange) — REQ-051.
  • Modules:
    • trex_core/adapters/messaging/topology.py — 큐명 빌더 + DIRECT/BROADCAST exchange 상수 + direct_routing_key
    • trex_core/adapters/messaging/rabbitmq.py — declare_topology(instance_key="default") + exchange 선언 + binding(direct per-instance + control dual) + (필요시) broadcast publish helper
    • trex_core/runtime/config.py — DaemonInstanceConfig + from_toml + from_config
    • trex_core/runtime/daemon.py — --config argparse(main) + instance_key 보관 + consumer 큐명에 instance_key 적용 + declare_topology(instance_key)
    • .gitignore — 인스턴스 TOML 패턴
  • Interfaces:
    • intent_queue(instance_key) -> str 등 (default 하위호환)
    • declare_topology(instance_key="default")
    • direct_routing_key(instance_key, channel_type) -> "{instance_key}.{channel_type}"
    • DaemonInstanceConfig.from_toml(path), DaemonConfig.from_config(toml_path)

Key Decisions

  1. default = 리터럴 큐명(특수 처리): FR-2(suffix)와 FR-5(default 무회귀)의 긴장을 해소 — named instance 만 suffix, default 는 기존 이름 유지. 기존 messaging 테스트/배포 무변경. (planning R-1)
  2. declare_topology 기본 인자 instance_key="default": 기존 호출부(transport.declare_topology())가 인자 없이도 default 동작 → 호출부 광범위 수정 회피.
  3. exchange 는 항상 선언(default 포함): direct/broadcast 는 default 인스턴스에서도 선언·바인딩하되, 기존 직접 큐 reply-to RPC 경로는 그대로 동작(추가 바인딩은 비파괴적). 기존 RPC 회귀 없음(FR-5/AC-6).
  4. TOML 우선 병합: from_config 는 from_env() 로 베이스 구성 후 TOML 의 portfolio_hub_token 을 PortfolioHubConfig.token 으로 override. instance_key 는 TOML 전용.
  5. --config 필수: argparse required. 누락 시 argparse 가 usage 출력 + exit≠0(OQ-2). 단, from_env() 단독 호출(테스트/라이브러리)은 계속 가능.
  6. pika per-thread: 바인딩 추가만, consumer 스레드/커넥션 수 불변(NFR-2).

Edge Cases

  • default 큐명 충돌 없음: *.default 를 쓰지 않고 리터럴 사용.
  • TOML 누락 필드/파일 부재 → 명확한 예외(FR-1/AC-4).
  • broadcast 중복 control 전달 → 핸들러 idempotency(REQ-036/advisory lock, R-3).
  • 기존 old 큐 잔류 → 자연 소멸(OQ-1), 코드 무관.
  • snapshot/intent reply-to RPC: 클라이언트가 direct routing key 로 보내든 직접 큐로 보내든, 인스턴스 큐가 direct 바인딩 + 직접 publish 둘 다 수신 가능(하위호환).

Architecture Impact

  • runtime-flows: TOML 기동 + directed/broadcast 라우팅 + split-brain 방지 — REQ-051.
  • project-structure: topology 동적화 + 설정 계층 + exchange — REQ-051.
  • interface-contract: routing key 계약 — REQ-051.

Reference Doc Update Plan

  • interface-contract.md: routing key({instance_key}.{channel_type})+broadcast+큐명 규칙 (REQ-051 AC-1)
  • runtime-flows.md: --config 기동 + directed/broadcast + split-brain (REQ-051 AC-2)
  • project-structure.md: 동적 큐명/DaemonInstanceConfig/--config/exchange (REQ-051 AC-3)