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>
4.4 KiB
4.4 KiB
BAT-013 Design
- Status: confirmed
- Batch: BAT-013
Architecture Summary
다중 인스턴스가 동일 RabbitMQ 에서 split-brain 없이 운영되도록 토폴로지·설정을 인스턴스화한다.
- 동적 큐명(
topology.py):intent_queue/snapshot_queue/control_queue(instance_key).instance_key in (None,"default")→ 기존 리터럴(trex.intent.req등), 그 외 →{base}.{instance_key}. 기존 상수는 default 값으로 보존(하위호환). - 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 바인딩. - 설정(
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). - 진입점(
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_keytrex_core/adapters/messaging/rabbitmq.py—declare_topology(instance_key="default")+ exchange 선언 + binding(direct per-instance + control dual) + (필요시) broadcast publish helpertrex_core/runtime/config.py—DaemonInstanceConfig+from_toml+from_configtrex_core/runtime/daemon.py—--configargparse(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
- default = 리터럴 큐명(특수 처리): FR-2(suffix)와 FR-5(default 무회귀)의 긴장을 해소 — named instance 만 suffix, default 는 기존 이름 유지. 기존 messaging 테스트/배포 무변경. (planning R-1)
- declare_topology 기본 인자
instance_key="default": 기존 호출부(transport.declare_topology())가 인자 없이도 default 동작 → 호출부 광범위 수정 회피. - exchange 는 항상 선언(default 포함): direct/broadcast 는 default 인스턴스에서도 선언·바인딩하되, 기존 직접 큐 reply-to RPC 경로는 그대로 동작(추가 바인딩은 비파괴적). 기존 RPC 회귀 없음(FR-5/AC-6).
- TOML 우선 병합:
from_config는from_env()로 베이스 구성 후 TOML 의portfolio_hub_token을 PortfolioHubConfig.token 으로 override.instance_key는 TOML 전용. --config필수: argparse required. 누락 시 argparse 가 usage 출력 + exit≠0(OQ-2). 단,from_env()단독 호출(테스트/라이브러리)은 계속 가능.- 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)