Files
document-haness/docs/clean-architecture-backend-template/final/evidence/rendered/a20-f006-grpcadmissioncontroller-tryadmit.svg
T
DongHyeonkaandClaude Opus 5 b2963105a8 docs(keycloak-session-store): import the session-storage lab as a new project
The keycloak project ended with four open questions that design could not
settle. A two-VM lab was built to answer them by measurement, and this is
that material: 26 experiments, 125 raw command outputs, 22 browser captures.

Follows the import procedure in README.md.

  source/     the originating repository verbatim — 78 documents, 28 SVGs,
              8 manifests, plus .source-revision recording the commit
  final/      the SSOT
    document.md   729 lines written from the 29 experiment documents, not
                  concatenated: what was predicted, what was measured, and
                  where the measurement itself was wrong
    evidence/raw    125 outputs, flattened to <experiment>__<file> because
                    the originals collided (01-baseline.txt appeared three
                    times) and the audit only globs the top level
    evidence/meta   one per raw file; command and exitCode are null and the
                    README says why rather than inventing them
    evidence/browser  22 captures
    assets/       three diagrams through techviz
    .techviz/     their VizSpecs

A separate project rather than an addition to keycloak: the B-layer answers
that project's four questions, but the A, C and D layers are about cluster
failure, SSO and operations, and one document.md should hold one subject.
The four question records there can point here through 관계.

Recorded rather than papered over: only three of the 28 diagrams were
remade. The repository forbids hand-drawn SVG and forbids titles inside the
canvas; all 28 originals carry both, so converting them is redrawing, not
reformatting. They stay in source/ and the gap is written into the document.

verify-pipeline.py passes. audit-records.py reports no issues.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 22:51:59 +09:00

230 lines
44 KiB
XML

<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="4308" viewBox="0 0 1200 4308" role="img">
<title>terminal evidence</title>
<desc>Terminal-style rendering generated from retained command output. Sensitive-looking values are redacted in the visual asset.</desc>
<rect x="1" y="1" width="1198" height="4306" rx="14" fill="#0d1117" stroke="#30363d"/>
<rect x="1" y="1" width="1198" height="44" rx="14" fill="#161b22"/>
<rect x="1" y="30" width="1198" height="14" fill="#161b22"/>
<circle cx="24" cy="22" r="6" fill="#ff5f57"/>
<circle cx="44" cy="22" r="6" fill="#febc2e"/>
<circle cx="64" cy="22" r="6" fill="#28c840"/>
<text x="92" y="27" fill="#8b949e" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace">terminal evidence</text>
<text x="24" y="68" fill="#c9d1d9" font-size="15" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">$ #!/bin/bash
set -euo pipefail
cd /shared/codebase/clean-architecture-backend-template
C=src/grpc/grpc-server/src/main/</tspan><tspan x="24" dy="22">java/dev/caskeleton/grpc/server/GrpcAdmissionController.java
echo &quot;# 승인 메서드 셋의 본문&quot;
awk &#x27;NR&gt;=50 &amp;&amp; NR&lt;=87 {prin</tspan><tspan x="24" dy="22">tf &quot; GrpcAdmissionController.java:%d %s\n&quot;, NR, $0}&#x27; $C
echo &quot; 계수기 필드 :&quot;
awk &#x27;NR&gt;=17 &amp;&amp; NR&lt;=19 {printf &quot; GrpcAdm</tspan><tspan x="24" dy="22">issionController.java:%d %s\n&quot;, NR, $0}&#x27; $C
echo
echo &quot;# 클래스가 자기 존재 이유를 무엇이라고 적는가&quot;
awk &#x27;NR&gt;=5 &amp;&amp; NR&lt;</tspan><tspan x="24" dy="22">=13 {printf &quot; GrpcAdmissionController.java:%d %s\n&quot;, NR, $0}&#x27; $C
echo
echo &quot;# 이 타입이 조립되는가, 그리고 승인 API 를</tspan><tspan x="24" dy="22"> 부르는 자리는 어디인가&quot;
git grep -n &#x27;GrpcAdmissionController&#x27; -- &#x27;src/grpc/**/*.java&#x27; \
| sed -E &#x27;s#^src/[^:]*/src/(m</tspan><tspan x="24" dy="22">ain|test)/java/dev/caskeleton/[^:]*/([^:/]+):([0-9]+):# \1 · \2:\3 #&#x27;
echo &quot; tryAdmit · promoteFromQueue · release </tspan><tspan x="24" dy="22">를 부르는 자리 :&quot;
git grep -nE &#x27;[.](tryAdmit|promoteFromQueue|release)[(][)]&#x27; -- &#x27;src/grpc/**/*.java&#x27; \
| sed -E &#x27;s#^s</tspan><tspan x="24" dy="22">rc/[^:]*/src/(main|test)/java/dev/caskeleton/[^:]*/([^:/]+):([0-9]+):# \1 · \2:\3 #&#x27;
m=$(git grep -lE &#x27;[.](tryAdmit|</tspan><tspan x="24" dy="22">promoteFromQueue|release)[(][)]&#x27; -- &#x27;src/grpc/**/*.java&#x27; | grep -c &#x27;/main/&#x27; || true)
echo &quot; 그중 main 소스 세트 : ${m</tspan><tspan x="24" dy="22">:-0} 개 파일&quot;
echo &quot; main 에서 이 타입을 들고 있는 GrpcDrainCoordinator 가 하는 일 :&quot;
grep -nE &#x27;admission[.]&#x27; src/grpc/</tspan><tspan x="24" dy="22">grpc-admin/src/main/java/dev/caskeleton/grpc/admin/GrpcDrainCoordinator.java \
| sed -E &#x27;s#^([0-9]+): *# GrpcDrainC</tspan><tspan x="24" dy="22">oordinator.java:\1 #&#x27;
echo &quot; 그 빈을 만드는 자동설정이 언제 켜지는가 :&quot;
A=src/grpc/grpc-spring-boot-starter/src/main/</tspan><tspan x="24" dy="22">java/dev/caskeleton/grpc/boot/GrpcPlatformAutoConfiguration.java
awk &#x27;NR&gt;=29 &amp;&amp; NR&lt;=36 {printf &quot; GrpcPlatformAutoConf</tspan><tspan x="24" dy="22">iguration.java:%d %s\n&quot;, NR, $0}&#x27; $A
n=$({ grep -rl &#x27;ca-skeleton.grpc.platform&#x27; --include=*.yml --include=*.yaml --inclu</tspan><tspan x="24" dy="22">de=*.properties src/ 2&gt;/dev/null || true; } | wc -l)
echo &quot; 그 프로퍼티를 켜는 설정 파일 : $n 개&quot;
m=$({ grep -rl &#x27;grp</tspan><tspan x="24" dy="22">c-spring-boot-starter&#x27; --include=build.gradle src/ 2&gt;/dev/null || true; } | { grep -v &#x27;^src/grpc/&#x27; || true; } | wc -l)
e</tspan><tspan x="24" dy="22">cho &quot; src/grpc 밖에서 이 starter 에 의존하는 모듈 : $m 개&quot;
echo &quot; main 소비자 GrpcDrainCoordinator 가 생성되는 자리 </tspan><tspan x="24" dy="22">:&quot;
git grep -n &#x27;new GrpcDrainCoordinator&#x27; -- &#x27;src/**/*.java&#x27; \
| sed -E &#x27;s#^src/[^:]*/src/(main|test)/java/dev/caskele</tspan><tspan x="24" dy="22">ton/[^:]*/([^:/]+):([0-9]+):# \1 · \2:\3 #&#x27;
k=$({ grep -rl &#x27;ApplicationContextRunner&#x27; src/grpc/ 2&gt;/dev/null || true;</tspan><tspan x="24" dy="22"> } | wc -l)
echo &quot; src/grpc 안의 ApplicationContextRunner : $k 개 파일&quot;
echo
echo &quot;# 저장소가 쓰는 승격 순서&quot;
awk &#x27;N</tspan><tspan x="24" dy="22">R&gt;=119 &amp;&amp; NR&lt;=131 {printf &quot; GrpcServerProfileTest.java:%d %s\n&quot;, NR, $0}&#x27; \
src/grpc/grpc-server/src/test/java/dev/ca</tspan><tspan x="24" dy="22">skeleton/grpc/server/GrpcServerProfileTest.java
echo
echo &quot;# 같은 가족의 올바른 형태 — 재시도 예산&quot;
B=$(git grep -l &#x27;c</tspan><tspan x="24" dy="22">lass GrpcRetryBudget&#x27; -- &#x27;src/grpc/**/*.java&#x27; | grep &#x27;/main/&#x27; | head -1)
echo &quot; $B&quot;
awk &#x27;NR&gt;=50 &amp;&amp; NR&lt;=61 {printf &quot; Gr</tspan><tspan x="24" dy="22">pcRetryBudget.java:%d %s\n&quot;, NR, $0}&#x27; &quot;$B&quot;
echo &quot; compareAndSet 을 쓰는 grpc main 파일 :&quot;
git grep -ln &#x27;compareAndSet&#x27; </tspan><tspan x="24" dy="22">-- &#x27;src/grpc/**/*.java&#x27; | grep &#x27;/main/&#x27; | sed &#x27;s#.*/# #&#x27;
for f in &quot;$C&quot; src/grpc/grpc-policy/src/main/java/dev/caskele</tspan><tspan x="24" dy="22">ton/grpc/streaming/GrpcStreamAdmission.java; do
printf &quot; %-28s compareAndSet %s 건\n&quot; &quot;$(basename $f)&quot; &quot;$(grep -c &#x27;</tspan><tspan x="24" dy="22">compareAndSet&#x27; $f || true)&quot;
done
echo
echo &quot;# 프로브 — 아래 소스를 그 자리에서 컴파일해 돌린다&quot;
grep -E &#x27;new GrpcAdmis</tspan><tspan x="24" dy="22">sionController|for [(]&#x27; /tmp/probe5/DeterministicProbe.java | sed &#x27;s/^ */ /&#x27;
cd /tmp/probe5
javac -nowarn -encoding U</tspan><tspan x="24" dy="22">TF-8 -cp &quot;$(cat /tmp/cp-grpc-server.txt)&quot; -d . DeterministicProbe.java
java -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=</tspan><tspan x="24" dy="22">UTF-8 \
-cp &quot;.:$(cat /tmp/cp-grpc-server.txt)&quot; DeterministicProbe
</tspan></text>
<text x="24" y="750" fill="#8b949e" font-size="13" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">cwd: /shared/codebase/clean-architecture-backend-template</tspan></text>
<text x="24" y="772" fill="#8b949e" font-size="13" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">time: 2026-09-04T02:57:28+00:00 · exit 0</tspan></text>
<line x1="24" y1="786" x2="1176" y2="786" stroke="#30363d"/>
<text x="24" y="826" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 승인 메서드 셋의 본문</tspan></text>
<text x="24" y="848" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:50 /** Admits a call, queues it, or refuses it. */</tspan></text>
<text x="24" y="870" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:51 public Decision tryAdmit() {</tspan></text>
<text x="24" y="892" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:52 int running = inFlight.get();</tspan></text>
<text x="24" y="914" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:53 if (running &lt; maxConcurrentCalls) {</tspan></text>
<text x="24" y="936" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:54 inFlight.incrementAndGet();</tspan></text>
<text x="24" y="958" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:55 return new Decision(true, inFlight.get(), queued.get(), &quot;within the concurrency bound&quot;);</tspan></text>
<text x="24" y="980" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:56 }</tspan></text>
<text x="24" y="1002" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:57 int waiting = queued.get();</tspan></text>
<text x="24" y="1024" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:58 if (waiting &lt; maxQueuedCalls) {</tspan></text>
<text x="24" y="1046" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:59 queued.incrementAndGet();</tspan></text>
<text x="24" y="1068" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:60 return new Decision(true, running, queued.get(), &quot;queued within the admission bound&quot;);</tspan></text>
<text x="24" y="1090" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:61 }</tspan></text>
<text x="24" y="1112" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:62 rejected.incrementAndGet();</tspan></text>
<text x="24" y="1134" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:63 return new Decision(</tspan></text>
<text x="24" y="1156" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:64 false,</tspan></text>
<text x="24" y="1178" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:65 running,</tspan></text>
<text x="24" y="1200" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:66 waiting,</tspan></text>
<text x="24" y="1222" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:67 &quot;at capacity: &quot;</tspan></text>
<text x="24" y="1244" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:68 + running</tspan></text>
<text x="24" y="1266" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:69 + &quot; in flight and &quot;</tspan></text>
<text x="24" y="1288" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:70 + waiting</tspan></text>
<text x="24" y="1310" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:71 + &quot; queued. Refusing is better than accepting work whose caller will have given up</tspan><tspan x="24" dy="22">.&quot;);</tspan></text>
<text x="24" y="1354" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:72 }</tspan></text>
<text x="24" y="1376" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:73 </tspan></text>
<text x="24" y="1398" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:74 /** Moves a queued call into execution. */</tspan></text>
<text x="24" y="1420" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:75 public void promoteFromQueue() {</tspan></text>
<text x="24" y="1442" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:76 if (queued.get() &gt; 0) {</tspan></text>
<text x="24" y="1464" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:77 queued.decrementAndGet();</tspan></text>
<text x="24" y="1486" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:78 inFlight.incrementAndGet();</tspan></text>
<text x="24" y="1508" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:79 }</tspan></text>
<text x="24" y="1530" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:80 }</tspan></text>
<text x="24" y="1552" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:81 </tspan></text>
<text x="24" y="1574" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:82 /** Releases a finished call. */</tspan></text>
<text x="24" y="1596" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:83 public void release() {</tspan></text>
<text x="24" y="1618" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:84 if (inFlight.get() &gt; 0) {</tspan></text>
<text x="24" y="1640" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:85 inFlight.decrementAndGet();</tspan></text>
<text x="24" y="1662" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:86 }</tspan></text>
<text x="24" y="1684" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:87 }</tspan></text>
<text x="24" y="1706" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 계수기 필드 :</tspan></text>
<text x="24" y="1728" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:17 private final AtomicInteger inFlight = new AtomicInteger();</tspan></text>
<text x="24" y="1750" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:18 private final AtomicInteger queued = new AtomicInteger();</tspan></text>
<text x="24" y="1772" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:19 private final AtomicInteger rejected = new AtomicInteger();</tspan></text>
<text x="24" y="1794" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="1816" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 클래스가 자기 존재 이유를 무엇이라고 적는가</tspan></text>
<text x="24" y="1838" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:5 /**</tspan></text>
<text x="24" y="1860" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:6 * Refuses work the server cannot do, before it spends anything on it.</tspan></text>
<text x="24" y="1882" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:7 *</tspan></text>
<text x="24" y="1904" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:8 * &lt;p&gt;Rejecting with {@code RESOURCE_EXHAUSTED} is a better outcome than queueing for two reaso</tspan><tspan x="24" dy="22">ns</tspan></text>
<text x="24" y="1948" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:9 * that both matter under load: the client learns immediately and can shed or retry elsewhere, </tspan><tspan x="24" dy="22">and</tspan></text>
<text x="24" y="1992" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:10 * the server stops accumulating work whose callers have already given up. A server that queue</tspan><tspan x="24" dy="22">s</tspan></text>
<text x="24" y="2036" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:11 * instead spends its capacity finishing requests nobody is reading.</tspan></text>
<text x="24" y="2058" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:12 */</tspan></text>
<text x="24" y="2080" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java:13 public final class GrpcAdmissionController {</tspan></text>
<text x="24" y="2102" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="2124" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 이 타입이 조립되는가, 그리고 승인 API 를 부르는 자리는 어디인가</tspan></text>
<text x="24" y="2146" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · GrpcDrainCoordinator.java:3 import dev.caskeleton.grpc.server.GrpcAdmissionController;</tspan></text>
<text x="24" y="2168" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · GrpcDrainCoordinator.java:25 private final GrpcAdmissionController admission;</tspan></text>
<text x="24" y="2190" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · GrpcDrainCoordinator.java:42 GrpcAdmissionController admission,</tspan></text>
<text x="24" y="2212" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · GrpcDrainCoordinatorTest.java:6 import dev.caskeleton.grpc.server.GrpcAdmissionController;</tspan></text>
<text x="24" y="2234" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · GrpcDrainCoordinatorTest.java:27 health, new GrpcAdmissionController(8, 8), policy, unaryCalls::get, streams::</tspan><tspan x="24" dy="22">get);</tspan></text>
<text x="24" y="2278" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · GrpcAdmissionController.java:13 public final class GrpcAdmissionController {</tspan></text>
<text x="24" y="2300" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · GrpcAdmissionController.java:22 public GrpcAdmissionController(int maxConcurrentCalls, int maxQueuedCalls) {</tspan></text>
<text x="24" y="2322" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · GrpcAdmissionController.java:31 public static GrpcAdmissionController forExecutor(GrpcExecutorProfile profile) {</tspan></text>
<text x="24" y="2344" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · GrpcAdmissionController.java:35 return new GrpcAdmissionController(</tspan></text>
<text x="24" y="2366" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · GrpcServerProfileTest.java:105 GrpcAdmissionController controller = new GrpcAdmissionController(2, 1);</tspan></text>
<text x="24" y="2388" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · GrpcServerProfileTest.java:110 GrpcAdmissionController.Decision refused = controller.tryAdmit();</tspan></text>
<text x="24" y="2410" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · GrpcServerProfileTest.java:122 GrpcAdmissionController controller = new GrpcAdmissionController(1, 1);</tspan></text>
<text x="24" y="2432" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · GrpcServerProfileTest.java:136 GrpcAdmissionController controller = GrpcAdmissionController.forExecutor(EXECUTOR);</tspan></text>
<text x="24" y="2454" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · GrpcPlatformAutoConfiguration.java:11 import dev.caskeleton.grpc.server.GrpcAdmissionController;</tspan></text>
<text x="24" y="2476" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · GrpcPlatformAutoConfiguration.java:56 public GrpcAdmissionController grpcAdmissionController(GrpcExecutorProfile exe</tspan><tspan x="24" dy="22">cutorProfile) {</tspan></text>
<text x="24" y="2520" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · GrpcPlatformAutoConfiguration.java:57 return GrpcAdmissionController.forExecutor(executorProfile);</tspan></text>
<text x="24" y="2542" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> tryAdmit · promoteFromQueue · release 를 부르는 자리 :</tspan></text>
<text x="24" y="2564" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · GrpcServerProfileTest.java:107 assertThat(controller.tryAdmit().admitted()).isTrue();</tspan></text>
<text x="24" y="2586" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · GrpcServerProfileTest.java:108 assertThat(controller.tryAdmit().admitted()).isTrue();</tspan></text>
<text x="24" y="2608" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · GrpcServerProfileTest.java:109 assertThat(controller.tryAdmit().admitted()).isTrue();</tspan></text>
<text x="24" y="2630" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · GrpcServerProfileTest.java:110 GrpcAdmissionController.Decision refused = controller.tryAdmit();</tspan></text>
<text x="24" y="2652" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · GrpcServerProfileTest.java:123 controller.tryAdmit();</tspan></text>
<text x="24" y="2674" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · GrpcServerProfileTest.java:124 controller.tryAdmit();</tspan></text>
<text x="24" y="2696" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · GrpcServerProfileTest.java:126 controller.release();</tspan></text>
<text x="24" y="2718" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · GrpcServerProfileTest.java:127 controller.promoteFromQueue();</tspan></text>
<text x="24" y="2740" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · GrpcServerProfileTest.java:139 assertThat(controller.tryAdmit().admitted()).isTrue();</tspan></text>
<text x="24" y="2762" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 그중 main 소스 세트 : 0 개 파일</tspan></text>
<text x="24" y="2784" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main 에서 이 타입을 들고 있는 GrpcDrainCoordinator 가 하는 일 :</tspan></text>
<text x="24" y="2806" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcDrainCoordinator.java:148 return admission.inFlight();</tspan></text>
<text x="24" y="2828" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 그 빈을 만드는 자동설정이 언제 켜지는가 :</tspan></text>
<text x="24" y="2850" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcPlatformAutoConfiguration.java:29 @Configuration(proxyBeanMethods = false)</tspan></text>
<text x="24" y="2872" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcPlatformAutoConfiguration.java:30 @ConditionalOnProperty(</tspan></text>
<text x="24" y="2894" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcPlatformAutoConfiguration.java:31 prefix = &quot;ca-skeleton.grpc.platform&quot;,</tspan></text>
<text x="24" y="2916" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcPlatformAutoConfiguration.java:32 name = &quot;enabled&quot;,</tspan></text>
<text x="24" y="2938" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcPlatformAutoConfiguration.java:33 havingValue = &quot;true&quot;,</tspan></text>
<text x="24" y="2960" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcPlatformAutoConfiguration.java:34 matchIfMissing = false)</tspan></text>
<text x="24" y="2982" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcPlatformAutoConfiguration.java:35 @EnableConfigurationProperties(GrpcPlatformProperties.class)</tspan></text>
<text x="24" y="3004" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcPlatformAutoConfiguration.java:36 public class GrpcPlatformAutoConfiguration {</tspan></text>
<text x="24" y="3026" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 그 프로퍼티를 켜는 설정 파일 : 0 개</tspan></text>
<text x="24" y="3048" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> src/grpc 밖에서 이 starter 에 의존하는 모듈 : 0 개</tspan></text>
<text x="24" y="3070" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main 소비자 GrpcDrainCoordinator 가 생성되는 자리 :</tspan></text>
<text x="24" y="3092" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · GrpcDrainCoordinatorTest.java:26 return new GrpcDrainCoordinator(</tspan></text>
<text x="24" y="3114" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> src/grpc 안의 ApplicationContextRunner : 0 개 파일</tspan></text>
<text x="24" y="3136" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="3158" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 저장소가 쓰는 승격 순서</tspan></text>
<text x="24" y="3180" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcServerProfileTest.java:119 @Test</tspan></text>
<text x="24" y="3202" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcServerProfileTest.java:120 @DisplayName(&quot;a released call makes room, and a queued call is promoted into it&quot;)</tspan></text>
<text x="24" y="3224" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcServerProfileTest.java:121 void releaseAndPromotionTrackCapacity() {</tspan></text>
<text x="24" y="3246" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcServerProfileTest.java:122 GrpcAdmissionController controller = new GrpcAdmissionController(1, 1);</tspan></text>
<text x="24" y="3268" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcServerProfileTest.java:123 controller.tryAdmit();</tspan></text>
<text x="24" y="3290" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcServerProfileTest.java:124 controller.tryAdmit();</tspan></text>
<text x="24" y="3312" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcServerProfileTest.java:125 </tspan></text>
<text x="24" y="3334" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcServerProfileTest.java:126 controller.release();</tspan></text>
<text x="24" y="3356" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcServerProfileTest.java:127 controller.promoteFromQueue();</tspan></text>
<text x="24" y="3378" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcServerProfileTest.java:128 </tspan></text>
<text x="24" y="3400" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcServerProfileTest.java:129 assertThat(controller.inFlight()).isEqualTo(1);</tspan></text>
<text x="24" y="3422" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcServerProfileTest.java:130 assertThat(controller.queued()).isZero();</tspan></text>
<text x="24" y="3444" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcServerProfileTest.java:131 }</tspan></text>
<text x="24" y="3466" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="3488" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 같은 가족의 올바른 형태 — 재시도 예산</tspan></text>
<text x="24" y="3510" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> src/grpc/grpc-policy/src/main/java/dev/caskeleton/grpc/resilience/GrpcRetryBudget.java</tspan></text>
<text x="24" y="3532" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcRetryBudget.java:50 public boolean tryConsume() {</tspan></text>
<text x="24" y="3554" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcRetryBudget.java:51 while (true) {</tspan></text>
<text x="24" y="3576" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcRetryBudget.java:52 long observed = tokens.get();</tspan></text>
<text x="24" y="3598" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcRetryBudget.java:53 if (observed &lt; tokensPerRetry) {</tspan></text>
<text x="24" y="3620" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcRetryBudget.java:54 return false;</tspan></text>
<text x="24" y="3642" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcRetryBudget.java:55 }</tspan></text>
<text x="24" y="3664" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcRetryBudget.java:56 if (tokens.compareAndSet(observed, observed - tokensPerRetry)) {</tspan></text>
<text x="24" y="3686" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcRetryBudget.java:57 return true;</tspan></text>
<text x="24" y="3708" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcRetryBudget.java:58 }</tspan></text>
<text x="24" y="3730" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcRetryBudget.java:59 }</tspan></text>
<text x="24" y="3752" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcRetryBudget.java:60 }</tspan></text>
<text x="24" y="3774" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcRetryBudget.java:61 </tspan></text>
<text x="24" y="3796" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> compareAndSet 을 쓰는 grpc main 파일 :</tspan></text>
<text x="24" y="3818" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcChannelRuntimeRegistry.java</tspan></text>
<text x="24" y="3840" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcCancellationToken.java</tspan></text>
<text x="24" y="3862" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcRetryBudget.java</tspan></text>
<text x="24" y="3884" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController.java compareAndSet 0 건</tspan></text>
<text x="24" y="3906" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcStreamAdmission.java compareAndSet 0 건</tspan></text>
<text x="24" y="3928" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="3950" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 프로브 — 아래 소스를 그 자리에서 컴파일해 돌린다</tspan></text>
<text x="24" y="3972" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController paired = new GrpcAdmissionController(1, 8);</tspan></text>
<text x="24" y="3994" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> for (int i = 0; i &lt; 6; i++) paired.tryAdmit();</tspan></text>
<text x="24" y="4016" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> for (int i = 0; i &lt; 5; i++) { paired.release(); paired.promoteFromQueue(); }</tspan></text>
<text x="24" y="4038" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> GrpcAdmissionController solo = new GrpcAdmissionController(1, 8);</tspan></text>
<text x="24" y="4060" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> for (int i = 0; i &lt; 6; i++) solo.tryAdmit();</tspan></text>
<text x="24" y="4082" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> for (int i = 0; i &lt; 5; i++) solo.promoteFromQueue();</tspan></text>
<text x="24" y="4104" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 가. 저장소 시험과 같은 순서 — 해제 하나에 승격 하나</tspan></text>
<text x="24" y="4126" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 여섯 번 승인 후 : 진행 중 1 · 대기 5</tspan></text>
<text x="24" y="4148" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 해제·승격을 다섯 쌍 후 : 진행 중 1 · 대기 0</tspan></text>
<text x="24" y="4170" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="4192" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 나. 해제 없이 승격만 — 승격이 해제를 앞지른 경우</tspan></text>
<text x="24" y="4214" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 여섯 번 승인 후 : 진행 중 1 · 대기 5</tspan></text>
<text x="24" y="4236" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 승격만 다섯 번 후 : 진행 중 6 · 대기 0</tspan></text>
<text x="24" y="4258" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 동시성 상한 : 1</tspan></text>
</svg>