--- kind: CONCEPT slug: adapter-outbound-cache-redis-c09 title: 구독 경로가 guard를 건너뛰고 대신 세우는 검사 topic: result-and-failure-algebra project: clean-architecture-backend-template status: 게시 전 sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 rootTreeNode: concept:adapter-outbound-cache-redis-c09 evidenceCapturedOn: 2026-09-01 assets: - key: adapter-outbound-cache-redis-c09 file: ../../../final/evidence/rendered/adapter-outbound-cache-redis-c09.svg evidence: - ../../../final/evidence/raw/adapter-outbound-cache-redis-c09.txt source: - 원본 분석 절은 analysis/10-adapter-outbound-cache-redis.md#L477 이다. module: adapter-outbound-cache-redis --- # 구독 경로가 guard를 건너뛰고 대신 세우는 검사 `PubSubOperationRequests`의 javadoc이 guard를 지나지 않는 경로를 스스로 밝히고, 그 자리에 어떤 검사를 대신 두었는지도 함께 적는다. 대체 검사는 실제로 존재한다. ## 본문 `PubSubOperationRequests`의 javadoc이 예외를 스스로 밝힌다. 발행은 보통의 명령이라 guard를 지나지만 구독은 지나지 않고, 경계 지을 응답도 적용할 타임아웃도 없어서 guard가 검사할 대상 자체가 없다는 것이 그 이유다. 대체 검사가 실제로 있다. ## 구독이 guard 대신 통과하는 세 검사 `channelTargets`·`shardTargets`·`patternTargets` 셋 다 빈 컬렉션을 거부하고 **모든 대상의 네임스페이스가 이 프로세스의 것과 같은지** 확인한다(`requireNamespace`, 다르면 "channel belongs to a namespace this process may not use"). `patternTargets`는 추가로 `context.sdkPermit(PATTERN_SUBSCRIBE)`를 호출한다. 팬아웃 폭을 요청이 아니라 서버가 정하기 때문이다. ## 코드베이스에 남은 PubSubOperationRequests 참조 :::evidence key="adapter-outbound-cache-redis-c09" alt="코드베이스에서 PubSubOperationRequests 를 검색한 출력 10줄. 이 기록이 세는 참조가 그 출력에 그대로 보인다." caption="PubSubOperationRequests 코드베이스 검색 — 10줄 · exit 0" zoom="true" :::