- analysis/·source-index·state.json 을 final/document.md 제2부·제3부로 접었다. SSOT 는 하나다 - 파일럿 — commit-ambiguity-as-a-result 를 새 기준으로 재선별. 후보 14 → 글감 5 (PROMOTE 5 · MERGE_INTO 3 · KEEP_IN_SSOT 4 · 보류 2). 기록 5건을 다시 썼고 그림 1개를 techviz 로 만들었다 - 재선별이 잡은 것: 제1부 §6.2·§11.1 이 자기 §13.2 와 어긋나 있었다(레인을 안 돌렸다 vs 돌렸다) — 정정. 이미 답이 나와 있던 Question 을 HEAD 재실행 질문으로 다시 세웠다. Concept 이 인용한 코드가 SSOT 에 없어 뺐다 - candidateScope·sourceRepository 기록. 나머지 43개 주제는 재선별 대기(PENDING 905) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
6.5 KiB
kind, slug, title, topic, project, status, sourceRevision, rootTreeNode, evidenceCapturedOn, body, assets, evidence, source
| kind | slug | title | topic | project | status | sourceRevision | rootTreeNode | evidenceCapturedOn | body | assets | evidence | source | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| CASE | analysis-finding-a16-f003 | 5계층 예산 모델에서 요청 계층만 강제되고, 나머지 파생이 전부 미배선이다 | graphql-surface | clean-architecture-backend-template | 게시 전 | 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 | case:analysis-finding-a16-f003 | 2026-09-01 | case-analysis-finding-a16-f003.body.md |
|
|
|
5계층 예산 모델에서 요청 계층만 강제되고, 나머지 파생이 전부 미배선이다
마감 전파기의 자바독이 다섯 계층이 왜 분리되는지 정확히 적는다. 그 파생을 수행하는 다섯 메서드 전부 프로덕션 호출자가 0 이다. 요청 전체 마감만 작동한다.
관계
- 스키마 조립과 계약 정체성과 해시 사슬이 통째로 미배선이고 그것을 발행할 엔드포인트도 등록되지 않는다 같은 리프의 다른 미배선 사슬이다.
- 용량 보호 계층 전체가 자기 테스트 픽스처 안에서만 실행된다 같은 형태의 미등록 사례다.
- 계층을 나눈 이유가 코드에 적혀 있어도 파생이 없으면 계층은 하나다 이 사례가 그 규칙의 형태다.
문제
이 리프는 마감을 다섯 계층으로 나눈다.
마감 전파기의 자바독이 그 이유를 적는다.
계층이 서로 다른 것을 뜻하고 서로 다른 시점에 만료되기 때문이라는 것이다. 전송 악수와 요청 실행과 하나의 해석기와 하나의 적재 배치, 그리고 구독의 경우 연결 자체다.
마지막 것은 의도적으로 요청 예산에서 파생하지 않는다는 것이다. 구독은 오래 사는 흐름이고 오 초 요청 시간 제한을 적용하면 모든 구독이 시작 오 초 뒤에 끝나기 때문이라는 것이다.
결론
그 파생을 수행하는 메서드 다섯 개 전부 프로덕션 호출자가 0 이다.
실제로 강제되는 것과 아닌 것이 갈린다.
요청 전체 마감은 작동한다. 플랫폼 인터셉터가 만들고 취소 장치가 끊는다.
개별 해석기가 남은 요청 예산으로 잘리는 것은 없다.
적재 배치 시간 제한이 남은 요청 예산으로 잘리는 것도 없다.
하류 호출에 남은 예산이 전달되는 것도 없다.
실패 시나리오는 이렇다.
요청 예산이 오 초이고 해석기 하나가 하류 호출을 부른다.
그 호출에 전달되는 마감은 나가는 어댑터 자신의 기본값이고, 남은 요청 예산이 일 초라는 사실은 전달되지 않는다.
요청은 오 초에 취소되지만 하류 호출은 계속 진행되어 연결과 스레드를 사 초 더 붙잡는다.
전파기의 하류 마감 메서드가 정확히 그 죄기를 위해 존재한다.
적재 쪽은 더 직접적이다.
배치 문맥이 마감을 레코드 성분으로 갖지만, 그 값을 남은 요청 예산으로 잘라 넣는 코드가 배치 시간 제한 메서드이고 호출자가 없다.
권고는 전파기를 빈으로 등록하고 세 지점에 연결하는 것이다.
배치 등록기가 배치 시간 제한을, 해석기 실행 경로가 해석기 예산을, 나가는 포트 호출 지점이 하류 마감을 쓰게 한다.
구독 계층은 별도 하위 범위에서 확인한다.
판정은 P2 다.
검증 환경
확인 방식 : 파생 메서드 호출자 계수와 강제 지점 확인 소스 수정 : x
재현 조건
원문은 final/evidence/raw/182 계열에 있다.
- 마감 전파기의 자바독을 읽는다.
- 파생 메서드 다섯을 나열한다.
- 각 메서드의 프로덕션 호출자를 센다.
- 요청 전체 마감이 어디서 만들어지고 어디서 끊기는지 확인한다.
- 배치 문맥이 마감을 어떻게 받는지 확인한다.
본문
GraphQlDeadlinePropagator의 javadoc이 계층 분리의 이유를 정확히 적는다.
"The layers are separate because they mean different things and expire at different points: a transport handshake, the request execution, one resolver, one DataLoader batch, and — for a subscription — the connection itself. The last one is deliberately not derived from the request budget: a subscription is a long-lived stream, and applying a five-second request timeout to it would terminate every subscription five seconds after it started."
GraphQlDeadlinePropagator 참조 위치
:::evidence key="analysis-finding-a16-f003" alt="코드베이스에서 GraphQlDeadlinePropagator 를 검색한 출력 2줄. 이 기록이 세는 참조가 그 출력에 그대로 보인다." caption="GraphQlDeadlinePropagator 코드베이스 검색 — 2줄 · exit 0" zoom="true" :::
파생 메서드 다섯 전부 호출자가 0이다
§11.1·§11.3.
강제되는 것과 아닌 것
요청 전체 데드라인은 GraphQlPlatformWebInterceptor가 만들고 GraphQlCancellation이 끊는다 — 작동한다. 개별 리졸버가 남은 요청 예산으로 잘리는 것, DataLoader 배치 타임아웃이 남은 요청 예산으로 잘리는 것, DB/HTTP 다운스트림 호출에 남은 예산이 전달되는 것은 없다.
실패 시나리오
요청 예산이 5초이고 리졸버 하나가 다운스트림 HTTP를 부른다. 그 호출에 전달되는 데드라인은 아웃바운드 어댑터 자신의 기본값(예: 10초)이고, 남은 요청 예산이 1초라는 사실은 전달되지 않는다. 요청은 5초에 취소되지만 다운스트림 호출은 계속 진행되어 연결과 스레드를 4초 더 붙잡는다. GraphQlDeadlinePropagator.downstreamDeadline이 정확히 그 clamping을 위해 존재한다. DataLoader 쪽은 더 직접적이다 — dataloader/GraphQlBatchContext가 GraphQlDeadline을 레코드 컴포넌트로 갖지만, 그 값을 남은 요청 예산으로 잘라 넣는 코드가 dataLoaderBatchTimeout이고 호출자가 없다. P2.
권고
GraphQlDeadlinePropagator를 빈으로 등록하고 세 지점에 연결한다 — GraphQlBatchLoaderRegistrar(autoconf=4)가 배치 타임아웃을, 리졸버 실행 경로가 resolverBudget을, 아웃바운드 포트 호출 지점이 downstreamDeadline을 쓰게 한다.
확인하지 못한 것
요청 취소 후 하류 호출이 계속되는 것을 실행으로 재현하지 않았다. 호출자 부재상 그 결과가 나온다.