Files
document-haness/docs/clean-architecture-backend-template/tech-log-studio/notification-and-delivery/case/case-analysis-finding-a13-f007.md
T
DongHyeonkaandClaude Fable 5.1 b25357c48a docs(clean-architecture-backend-template): fold analysis into final and re-select one topic
- 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>
2026-09-07 12:39:20 +09:00

5.0 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-a13-f007 "상한을 두고 읽는다"는 본문 핸들러가 전부 읽은 뒤에 자른다 notification-and-delivery clean-architecture-backend-template 게시 전 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 case:analysis-finding-a13-f007 2026-09-01 case-analysis-finding-a13-f007.body.md
key file
analysis-finding-a13-f007 ../../../final/evidence/rendered/analysis-finding-a13-f007.svg
../../../final/evidence/raw/analysis-finding-a13-f007.txt
원본 분석 절은 final/document.md#a13#L795 이다.

"상한을 두고 읽는다"는 본문 핸들러가 전부 읽은 뒤에 자른다

자바독이 상한에서 읽기를 멈춘다고 적는다. 구현은 무제한 상류 구독자의 결과에 자르기 함수를 얹는다. 자르기는 전체가 힙에 모인 다음에 일어난다. 호출부 주석이 쓰지 말라고 명시한 바로 그 상류를 두 줄 아래 함수가 쓴다.

관계

  • 음수 Retry-After 가 확정 거절을 영구 중지되는 모호한 제출로 바꾼다 같은 리프의 다른 원격 입력 사례다.
  • 이름이 상한을 말한다고 상한이 걸리는 것은 아니다 이 사례가 그 규칙의 형태다.
  • 두 연산자가 이름만 있고 아무것도 하지 않는다 같은 계열의 서술과 코드 어긋남이다.

문제

응답 본문을 읽는 처리기가 있다. 자바독이 상한에서 읽기를 멈추는 본문 처리기라고 적는다.

호출부 주석도 이유를 길게 적는다.

제공자 응답은 진단이라는 것이다. 상태와 헤더 몇 개와 오류 문서라는 것이다. 상한 없이 읽으면 보내는 쪽의 힙이 저쪽이 보내기로 한 양의 함수가 된다는 것이다. 끝나지 않는 조각 응답은 요청 하나짜리 장애라는 것이다.

결론

구현이 그것을 하지 않는다.

바이트 배열 구독자를 상류로 두고 그 결과에 자르기 함수를 얹는다.

사상 구독자의 마무리 함수는 상류가 완료된 뒤 그 결과에 적용된다.

상류는 무제한으로 요청하여 본문 전체를 힙에 모은다. 자르기는 그다음이다.

호출부 주석이 막겠다고 선언한 것과 정확히 반대다.

주석은 그 상류를 쓰지 말라고 쓰여 있고, 두 줄 아래 함수가 그것을 상류로 쓴다.

실패 시나리오는 이렇다.

제공자나 그 자리에 들어온 무엇이든 응답으로 큰 본문을 빠르게 보낸다.

요청 시간 제한이 시간은 제한하므로 끝나지 않는 조각 응답은 시간 제한에서 끊긴다.

그러나 주석이 두 번째로 든 위험은 그대로다. 보내는 쪽의 힙이 저쪽이 보내기로 한 양의 함수가 되는 상황이다.

시간 제한 안에 수 기가바이트를 받을 수 있는 연결에서는 그만큼이 전부 배열로 쌓인 뒤 상한 크기로 잘린다.

동시 발송이 많을수록 배수로 늘어난다. 이 리프는 발송 작업자가 가상 스레드로 퍼져 나간다.

판정은 P2 다.

검증 환경

OpenJDK : 21.0.12 확인 방식 : 구현과 자바독, 호출부 주석 대조 소스 수정 : x

재현 조건

원문은 final/evidence/raw/173 계열에 있다.

  1. 본문 처리기의 자바독을 읽는다.
  2. 구현이 어떤 상류 구독자를 쓰는지 확인한다.
  3. 사상 구독자의 마무리 함수가 언제 적용되는지 확인한다.
  4. 호출부 주석을 읽는다.
  5. 주석이 배제한 상류와 구현의 상류를 대조한다.

본문

본문 핸들러는 다음이다.

// JdkNotificationHttpGateway.java:116-128
/**
 * A body handler that stops reading at the cap.
 */
private static HttpResponse.BodyHandler<byte[]> boundedBody(int maxBytes) {
  return responseInfo ->
      HttpResponse.BodySubscribers.mapping(
          HttpResponse.BodySubscribers.ofByteArray(),
          body -> body.length <= maxBytes ? body : java.util.Arrays.copyOf(body, maxBytes));
}

본문 핸들러가 도는 순서

:::evidence key="analysis-finding-a13-f007" alt="분석 문서 final/document.md#a13 에서 이 기록의 근거 절을 그대로 잘라낸 15줄. 코드베이스를 측정한 것이 아니라 원본 판정이 무엇을 적었는지를 보여 준다." caption="final/document.md#a13 발췌 — 15줄" zoom="true" :::

finisher는 upstream이 끝난 뒤에 돈다

BodySubscribers.mapping(upstream, finisher)의 finisher는 upstream이 완료된 뒤 그 결과에 적용된다. upstream은 ofByteArray()이고, 그것은 무제한으로 요청하여 본문 전체를 힙에 모은다. 잘라내기는 그 다음이다.

호출부 주석이 선언한 것과 정확히 반대다

:60-62 — "Bounded, not ofByteArray(). A provider response is diagnostic — a status, some headers, an…". P2.

확인하지 못한 것

큰 응답을 보내는 가짜 제공자로 힙 증가를 측정하지 않았다. 구독자 규약상 그 결과가 나온다.