Files
document-haness/docs/clean-architecture-backend-template/final/evidence/rendered/an-order-contract-with-no-implementation.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

318 lines
54 KiB
XML

<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="5540" viewBox="0 0 1200 5540" 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="5538" 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
shopt -s inherit_errexit
cd /shared/codebase/clean-architecture-backend-template
named(</tspan><tspan x="24" dy="22">) { # 이름이 저장소에 아예 없으면 오타이므로 죽는다
local out rc
git grep -qE &quot;$1&quot; || { echo &quot;NA</tspan><tspan x="24" dy="22">ME NOT FOUND: $1&quot; &gt;&amp;2; exit 3; }
out=$(git grep -nE &quot;$1&quot; -- &quot;$2&quot;) &amp;&amp; rc=0 || rc=$?
[ &quot;$rc&quot; -le 1 ] || { echo &quot;SEARCH</tspan><tspan x="24" dy="22"> FAILED rc=$rc : $1&quot; &gt;&amp;2; exit 2; }
[ &quot;$rc&quot; -eq 0 ] &amp;&amp; printf &#x27;%s\n&#x27; &quot;$out&quot; || true
}
mod() { sed -E &#x27;s#^src/(.*)/src/</tspan><tspan x="24" dy="22">(main|test)/java/.*/([A-Za-z]+\.java):([0-9]+):# \1 · \2 · \3:\4 #&#x27;; }
L=src/messaging/messaging-transport-spi/src/</tspan><tspan x="24" dy="22">main/java/dev/caskeleton/messaging/transport/MessagingLifecycle.java
T=src/messaging/messaging-transport-spi/src/test/ja</tspan><tspan x="24" dy="22">va/dev/caskeleton/messaging/transport/MessagingLifecycleTest.java
test -f &quot;$L&quot; &amp;&amp; test -f &quot;$T&quot;
echo &quot;# MessagingLifecyc</tspan><tspan x="24" dy="22">le 전문 ($(wc -l &lt; &quot;$L&quot;) 줄)&quot;
awk &#x27;{printf &quot; MessagingLifecycle.java:%d %s\n&quot;, NR, $0}&#x27; &quot;$L&quot;
echo &quot; ShutdownPhase 상수</tspan><tspan x="24" dy="22"> 개수 : $(sed -n &#x27;/enum ShutdownPhase/,/^ }$/p&#x27; &quot;$L&quot; | grep -cE &#x27;^ [A-Z_]+&#x27; || true) 개&quot;
echo &quot; 인터페이스가 요구하</tspan><tspan x="24" dy="22">는 메서드 :&quot;
grep -nE &#x27;^ [A-Za-z].*\(.*\);&#x27; &quot;$L&quot; | sed -E &#x27;s#^([0-9]+): *# :\1 #&#x27;
echo
echo &quot;# MessagingLifecycleT</tspan><tspan x="24" dy="22">est 전문 ($(wc -l &lt; &quot;$T&quot;) 줄)&quot;
awk &#x27;{printf &quot; MessagingLifecycleTest.java:%d %s\n&quot;, NR, $0}&#x27; &quot;$T&quot;
echo
echo &quot;# 그 두 </tspan><tspan x="24" dy="22">이름을 저장소 어디서 쓰는가&quot;
echo &quot; pathspec 없이 이름이 나오는 파일 전부 :&quot;
git grep -l &#x27;MessagingLifecycle\|ShutdownP</tspan><tspan x="24" dy="22">hase&#x27; | sed &#x27;s#^# #&#x27;
count() { # 세 갈래를 구분해 출력한다. git 오류면 죽는다.
local out rc
o</tspan><tspan x="24" dy="22">ut=$(git grep -lE &quot;$1&quot; -- &#x27;src/**/*.java&#x27;) &amp;&amp; rc=0 || rc=$?
[ &quot;$rc&quot; -le 1 ] || { echo &quot;SEARCH FAILED rc=$rc : $1&quot; &gt;&amp;2;</tspan><tspan x="24" dy="22"> exit 2; }
[ &quot;$rc&quot; -eq 0 ] &amp;&amp; printf &#x27;%s\n&#x27; &quot;$out&quot; | grep -c . || echo 0
}
IMPL=&#x27;implements[[:space:]]+([A-Za-z0-9_.]+</tspan><tspan x="24" dy="22">,[[:space:]]*)*&#x27;
echo &quot; implements MessagingLifecycle 를 가진 파일 : $(count &quot;${IMPL}MessagingLifecycle&quot;) 개&quot;
echo &quot; [</tspan><tspan x="24" dy="22">자기시험] implements MessagingLifecycleZZZ 를 가진 파일 : $(count &quot;${IMPL}MessagingLifecycleZZZ&quot;) 개 (0 이어야 정상)&quot;
ec</tspan><tspan x="24" dy="22">ho &quot; [대조] implements MessagingTransport 를 가진 파일 : $(count &quot;${IMPL}MessagingTransport&quot;) 개 (0 이면 검색식이 깨진 </tspan><tspan x="24" dy="22">것)&quot;
named &quot;${IMPL}MessagingTransport&quot; &#x27;src/**/*.java&#x27; | mod
echo
echo &quot;# DEFAULT_DRAIN_DEADLINE 이라는 이름을 가진 선</tspan><tspan x="24" dy="22">언과 그 사용처&quot;
named &#x27;DEFAULT_DRAIN_DEADLINE&#x27; &#x27;src/**/*.java&#x27; | mod
echo
echo &quot;# 프로퍼티로 들어오는 드레인 마감과 그</tspan><tspan x="24" dy="22">것을 받는 자리&quot;
named &#x27;drainDeadline = Duration\.ofSeconds|getShutdown\(\)\.getDrainDeadline\(\)&#x27; &#x27;src/**/*.java&#x27; | mod
</tspan><tspan x="24" dy="22">
echo
echo &quot;# 오늘 종료를 담당하는 구현&quot;
named &#x27;class MessagingShutdownLifecycle|class MessagingOutboxRelayLifecycle&#x27; &#x27;s</tspan><tspan x="24" dy="22">rc/**/*.java&#x27; | mod
echo
echo &quot;# 열거형 상수 순서를 바꾸면 무엇이 깨지는가 (레포 사본을 /tmp 에서 컴파일)&quot;
G=/root/.gra</tspan><tspan x="24" dy="22">dle/caches/modules-2/files-2.1
CP=$(find $G -name &#x27;junit-jupiter-api-*.jar&#x27; -o -name &#x27;assertj-core-*.jar&#x27; \
-o -</tspan><tspan x="24" dy="22">name &#x27;apiguardian-api-*.jar&#x27; -o -name &#x27;opentest4j-*.jar&#x27; | sort | tr &#x27;\n&#x27; &#x27;:&#x27;)
D=/tmp/reorder/src/dev/caskeleton/messagi</tspan><tspan x="24" dy="22">ng/transport
rm -rf /tmp/reorder &amp;&amp; mkdir -p &quot;$D&quot;
cp &quot;$L&quot; &quot;$T&quot; &quot;$D/&quot;
cat &gt; &quot;$D/RunPhaseTests.java&quot; &lt;&lt;&#x27;JAVA&#x27;
package dev.</tspan><tspan x="24" dy="22">caskeleton.messaging.transport;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collectio</tspan><tspan x="24" dy="22">ns;
import java.util.List;
public final class RunPhaseTests {
public static void main(String[] args) throws Exception</tspan><tspan x="24" dy="22"> {
MessagingLifecycleTest t = new MessagingLifecycleTest();
List&lt;String&gt; names = new ArrayList&lt;&gt;();
for (Met</tspan><tspan x="24" dy="22">hod m : MessagingLifecycleTest.class.getDeclaredMethods()) {
if (m.getParameterCount() == 0 &amp;&amp; !m.getName().contai</tspan><tspan x="24" dy="22">ns(&quot;$&quot;)) names.add(m.getName());
}
Collections.sort(names);
List&lt;String&gt; failed = new ArrayList&lt;&gt;();
int</tspan><tspan x="24" dy="22"> pass = 0;
for (String n : names) {
Method m = MessagingLifecycleTest.class.getDeclaredMethod(n);
m.setA</tspan><tspan x="24" dy="22">ccessible(true);
try {
m.invoke(t);
pass++;
} catch (Exception e) {
failed.add(n);
</tspan><tspan x="24" dy="22"> }
}
System.out.printf(&quot; 통과 %d · 실패 %d%n&quot;, pass, failed.size());
for (String n : failed) {
</tspan><tspan x="24" dy="22"> System.out.println(&quot; 깨진 시험 : &quot; + n);
}
}
}
JAVA
run() {
rm -rf /tmp/reorder/out &amp;&amp; mkdir -p /tmp/reord</tspan><tspan x="24" dy="22">er/out
javac -nowarn -cp &quot;$CP&quot; -d /tmp/reorder/out &quot;$D&quot;/*.java 2&gt;/dev/null
java -Dfile.encoding=UTF-8 -Dsun.stdout.e</tspan><tspan x="24" dy="22">ncoding=UTF-8 \
-cp &quot;$CP:/tmp/reorder/out&quot; dev.caskeleton.messaging.transport.RunPhaseTests
}
echo &quot; 사본을 그대로 </tspan><tspan x="24" dy="22">컴파일했을 때&quot;
run
python3 - &quot;$D/MessagingLifecycle.java&quot; &lt;&lt;&#x27;PY&#x27;
import sys
p = sys.argv[1]
lines = open(p).read().split</tspan><tspan x="24" dy="22">(&#x27;\n&#x27;)
i = [n for n, l in enumerate(lines) if l.strip().startswith(&#x27;CLOSE_CONNECTIONS&#x27;)][0]
lines[i] = &#x27;XX_DROP&#x27;
j = [n </tspan><tspan x="24" dy="22">for n, l in enumerate(lines) if l.strip().startswith(&#x27;STOP_PUBLISH_ADMISSION&#x27;)][0]
lines[j] = &#x27; CLOSE_CONNECTIONS,\n </tspan><tspan x="24" dy="22"> STOP_PUBLISH_ADMISSION,&#x27;
txt = &#x27;\n&#x27;.join(l for l in lines if l != &#x27;XX_DROP&#x27;)
open(p, &#x27;w&#x27;).write(txt.replace(&#x27;RELEASE_</tspan><tspan x="24" dy="22">OUTBOX_LEASES,&#x27;, &#x27;RELEASE_OUTBOX_LEASES&#x27;))
PY
echo &quot; CLOSE_CONNECTIONS 를 첫 상수로 옮겼을 때&quot;
run
echo &quot; 레포가 수정</tspan><tspan x="24" dy="22">되지 않았는지 : $(git status --porcelain | grep -c . || true) 건 변경&quot;
</tspan></text>
<text x="24" y="1014" 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="1036" 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-04T04:30:09+00:00 · exit 0</tspan></text>
<line x1="24" y1="1050" x2="1176" y2="1050" stroke="#30363d"/>
<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"># MessagingLifecycle 전문 (67 줄)</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"> MessagingLifecycle.java:1 package dev.caskeleton.messaging.transport;</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"> MessagingLifecycle.java:2 </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"> MessagingLifecycle.java:3 import java.time.Duration;</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"> MessagingLifecycle.java:4 </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"> MessagingLifecycle.java:5 /**</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"> MessagingLifecycle.java:6 * The ordered lifecycle every messaging runtime implements.</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"> MessagingLifecycle.java:7 *</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"> MessagingLifecycle.java:8 * &lt;p&gt;The order in {@link ShutdownPhase} is the contract, not an implementation detail. Closing</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"> MessagingLifecycle.java:9 * connections before settlements have been transmitted loses the settlements, and pausing consumers</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"> MessagingLifecycle.java:10 * after draining lets fresh deliveries arrive into a runtime that is already shutting down. Each</tspan></text>
<text x="24" y="1332" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> MessagingLifecycle.java:11 * adapter implements the phases; none of them chooses the order.</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"> MessagingLifecycle.java:12 *</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"> MessagingLifecycle.java:13 * &lt;p&gt;Implementations are driven by the Spring lifecycle rather than a JVM shutdown hook alone. A</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"> MessagingLifecycle.java:14 * shutdown hook runs after the context has already begun disposing beans, so a handler mid-drain</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"> MessagingLifecycle.java:15 * can find its datasource closed underneath it.</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"> MessagingLifecycle.java:16 */</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"> MessagingLifecycle.java:17 public interface MessagingLifecycle {</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"> MessagingLifecycle.java:18 </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"> MessagingLifecycle.java:19 /** The fixed phases of an orderly shutdown, in the order they must run. */</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"> MessagingLifecycle.java:20 enum ShutdownPhase {</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"> MessagingLifecycle.java:21 /** Refuse new publishes. Nothing in flight is affected. */</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"> MessagingLifecycle.java:22 STOP_PUBLISH_ADMISSION,</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"> MessagingLifecycle.java:23 /** Refuse to start new delivery handlers. */</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"> MessagingLifecycle.java:24 STOP_NEW_HANDLERS,</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"> MessagingLifecycle.java:25 /** Ask the broker to stop delivering. */</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"> MessagingLifecycle.java:26 PAUSE_CONSUMERS,</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"> MessagingLifecycle.java:27 /** Let running handlers finish. */</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"> MessagingLifecycle.java:28 DRAIN_HANDLERS,</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"> MessagingLifecycle.java:29 /** Transmit the settlements those handlers produced. */</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"> MessagingLifecycle.java:30 FLUSH_SETTLEMENTS,</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"> MessagingLifecycle.java:31 /** Wait for outstanding producer confirms so publishes are not left ambiguous. */</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"> MessagingLifecycle.java:32 AWAIT_PRODUCER_CONFIRMS,</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"> MessagingLifecycle.java:33 /** Return outbox leases so another relay can claim the rows immediately. */</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"> MessagingLifecycle.java:34 RELEASE_OUTBOX_LEASES,</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"> MessagingLifecycle.java:35 /** Close connections and channels. */</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"> MessagingLifecycle.java:36 CLOSE_CONNECTIONS</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"> MessagingLifecycle.java:37 }</tspan></text>
<text x="24" y="1926" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> MessagingLifecycle.java:38 </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"> MessagingLifecycle.java:39 /** The default drain budget from the design. */</tspan></text>
<text x="24" y="1970" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> MessagingLifecycle.java:40 Duration DEFAULT_DRAIN_DEADLINE = Duration.ofSeconds(30);</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"> MessagingLifecycle.java:41 </tspan></text>
<text x="24" y="2014" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> MessagingLifecycle.java:42 /**</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"> MessagingLifecycle.java:43 * Starts the runtime.</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"> MessagingLifecycle.java:44 *</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"> MessagingLifecycle.java:45 * @throws IllegalStateException when the runtime was already started</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"> MessagingLifecycle.java:46 */</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"> MessagingLifecycle.java:47 void start();</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"> MessagingLifecycle.java:48 </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"> MessagingLifecycle.java:49 /**</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"> MessagingLifecycle.java:50 * Runs the shutdown phases in order, bounded by the drain deadline.</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"> MessagingLifecycle.java:51 *</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"> MessagingLifecycle.java:52 * &lt;p&gt;Work still running at the deadline is abandoned &lt;em&gt;unsettled&lt;/em&gt; so the broker redelivers</tspan></text>
<text x="24" y="2256" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> MessagingLifecycle.java:53 * it. Unconfirmed publishes are recorded as ambiguous rather than as successes.</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"> MessagingLifecycle.java:54 *</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"> MessagingLifecycle.java:55 * @param drainDeadline how long in-flight work may take</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"> MessagingLifecycle.java:56 * @return the phase that was still running when the deadline passed, or {@link</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"> MessagingLifecycle.java:57 * ShutdownPhase#CLOSE_CONNECTIONS} when the shutdown completed</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"> MessagingLifecycle.java:58 */</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"> MessagingLifecycle.java:59 ShutdownPhase shutdown(Duration drainDeadline);</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"> MessagingLifecycle.java:60 </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"> MessagingLifecycle.java:61 /**</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"> MessagingLifecycle.java:62 * Reports whether the runtime is running and accepting work.</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"> MessagingLifecycle.java:63 *</tspan></text>
<text x="24" y="2498" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> MessagingLifecycle.java:64 * @return true between {@link #start()} and the first shutdown phase</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"> MessagingLifecycle.java:65 */</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"> MessagingLifecycle.java:66 boolean isRunning();</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"> MessagingLifecycle.java:67 }</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"> ShutdownPhase 상수 개수 : 8 개</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"> 인터페이스가 요구하는 메서드 :</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"> :40 Duration DEFAULT_DRAIN_DEADLINE = Duration.ofSeconds(30);</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"> :47 void start();</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"> :59 ShutdownPhase shutdown(Duration drainDeadline);</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"> :66 boolean isRunning();</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"></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"># MessagingLifecycleTest 전문 (59 줄)</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"> MessagingLifecycleTest.java:1 package dev.caskeleton.messaging.transport;</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"> MessagingLifecycleTest.java:2 </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"> MessagingLifecycleTest.java:3 import static org.assertj.core.api.Assertions.assertThat;</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"> MessagingLifecycleTest.java:4 </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"> MessagingLifecycleTest.java:5 import dev.caskeleton.messaging.transport.MessagingLifecycle.ShutdownPhase;</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"> MessagingLifecycleTest.java:6 import java.time.Duration;</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"> MessagingLifecycleTest.java:7 import java.util.List;</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"> MessagingLifecycleTest.java:8 import org.junit.jupiter.api.Test;</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"> MessagingLifecycleTest.java:9 </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"> MessagingLifecycleTest.java:10 class MessagingLifecycleTest {</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"> MessagingLifecycleTest.java:11 </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"> MessagingLifecycleTest.java:12 @Test</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"> MessagingLifecycleTest.java:13 void publishAdmissionClosesBeforeConsumersArePaused() {</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"> MessagingLifecycleTest.java:14 List&lt;ShutdownPhase&gt; order = List.of(ShutdownPhase.values());</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"> MessagingLifecycleTest.java:15 </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"> MessagingLifecycleTest.java:16 assertThat(order.indexOf(ShutdownPhase.STOP_PUBLISH_ADMISSION))</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"> MessagingLifecycleTest.java:17 .isLessThan(order.indexOf(ShutdownPhase.PAUSE_CONSUMERS));</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"> MessagingLifecycleTest.java:18 }</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"> MessagingLifecycleTest.java:19 </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"> MessagingLifecycleTest.java:20 @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"> MessagingLifecycleTest.java:21 void handlersDrainBeforeTheirSettlementsAreFlushed() {</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"> MessagingLifecycleTest.java:22 List&lt;ShutdownPhase&gt; order = List.of(ShutdownPhase.values());</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"> MessagingLifecycleTest.java:23 </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"> MessagingLifecycleTest.java:24 assertThat(order.indexOf(ShutdownPhase.DRAIN_HANDLERS))</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"> MessagingLifecycleTest.java:25 .as(&quot;flushing before the handlers finish would lose the settlements they produce&quot;)</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"> MessagingLifecycleTest.java:26 .isLessThan(order.indexOf(ShutdownPhase.FLUSH_SETTLEMENTS));</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"> MessagingLifecycleTest.java:27 }</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"> MessagingLifecycleTest.java:28 </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"> MessagingLifecycleTest.java:29 @Test</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"> MessagingLifecycleTest.java:30 void connectionsCloseLastOfAll() {</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"> MessagingLifecycleTest.java:31 ShutdownPhase[] order = ShutdownPhase.values();</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"> MessagingLifecycleTest.java:32 </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"> MessagingLifecycleTest.java:33 assertThat(order[order.length - 1])</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"> MessagingLifecycleTest.java:34 .as(&quot;every earlier phase needs the connection that this one closes&quot;)</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"> MessagingLifecycleTest.java:35 .isEqualTo(ShutdownPhase.CLOSE_CONNECTIONS);</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"> MessagingLifecycleTest.java:36 }</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"> MessagingLifecycleTest.java:37 </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"> MessagingLifecycleTest.java:38 @Test</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"> MessagingLifecycleTest.java:39 void producerConfirmsAreAwaitedBeforeTheConnectionGoesAway() {</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"> MessagingLifecycleTest.java:40 List&lt;ShutdownPhase&gt; order = List.of(ShutdownPhase.values());</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"> MessagingLifecycleTest.java:41 </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"> MessagingLifecycleTest.java:42 assertThat(order.indexOf(ShutdownPhase.AWAIT_PRODUCER_CONFIRMS))</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"> MessagingLifecycleTest.java:43 .as(&quot;a confirm that arrives after close cannot be observed, leaving the publish ambiguo</tspan><tspan x="24" dy="22">us&quot;)</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"> MessagingLifecycleTest.java:44 .isLessThan(order.indexOf(ShutdownPhase.CLOSE_CONNECTIONS));</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"> MessagingLifecycleTest.java:45 }</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"> MessagingLifecycleTest.java:46 </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"> MessagingLifecycleTest.java:47 @Test</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"> MessagingLifecycleTest.java:48 void outboxLeasesAreReleasedBeforeClosing() {</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"> MessagingLifecycleTest.java:49 List&lt;ShutdownPhase&gt; order = List.of(ShutdownPhase.values());</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"> MessagingLifecycleTest.java:50 </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"> MessagingLifecycleTest.java:51 assertThat(order.indexOf(ShutdownPhase.RELEASE_OUTBOX_LEASES))</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"> MessagingLifecycleTest.java:52 .isLessThan(order.indexOf(ShutdownPhase.CLOSE_CONNECTIONS));</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"> MessagingLifecycleTest.java:53 }</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"> MessagingLifecycleTest.java:54 </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"> MessagingLifecycleTest.java:55 @Test</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"> MessagingLifecycleTest.java:56 void theDefaultDrainDeadlineMatchesTheDesign() {</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"> MessagingLifecycleTest.java:57 assertThat(MessagingLifecycle.DEFAULT_DRAIN_DEADLINE).isEqualTo(Duration.ofSeconds(30));</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"> MessagingLifecycleTest.java:58 }</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"> MessagingLifecycleTest.java:59 }</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"></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"> pathspec 없이 이름이 나오는 파일 전부 :</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"> docs/superpowers/plans/2026-08-10-messaging-platform-implementation-plan.md</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"> src/messaging/messaging-transport-spi/src/main/java/dev/caskeleton/messaging/transport/MessagingLifecycle.java</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"> src/messaging/messaging-transport-spi/src/test/java/dev/caskeleton/messaging/transport/MessagingLifecycleTest.java</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"> implements MessagingLifecycle 를 가진 파일 : 0 개</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"> [자기시험] implements MessagingLifecycleZZZ 를 가진 파일 : 0 개 (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"> [대조] implements MessagingTransport 를 가진 파일 : 6 개 (0 이면 검색식이 깨진 것)</tspan></text>
<text x="24" y="4280" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-kafka · main · KafkaMessagingTransport.java:41 public final class KafkaMessagingTransport implements Me</tspan><tspan x="24" dy="22">ssagingTransport {</tspan></text>
<text x="24" y="4324" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-nats-experimental · main · NatsJetStreamTransport.java:54 public final class NatsJetStreamTransport imp</tspan><tspan x="24" dy="22">lements MessagingTransport {</tspan></text>
<text x="24" y="4368" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-pulsar-experimental · main · PulsarMessagingTransport.java:47 public final class PulsarMessagingTranspo</tspan><tspan x="24" dy="22">rt implements MessagingTransport {</tspan></text>
<text x="24" y="4412" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-rabbit · main · RabbitMessagingTransport.java:39 public final class RabbitMessagingTransport implements</tspan><tspan x="24" dy="22"> MessagingTransport {</tspan></text>
<text x="24" y="4456" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-runtime-core · test · DefaultMessagePublisherTest.java:426 private static final class RecordingTransp</tspan><tspan x="24" dy="22">ort implements MessagingTransport {</tspan></text>
<text x="24" y="4500" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-transport-spi · test · MessagingRuntimeRegistryTest.java:230 final class FakeTransport implements Messa</tspan><tspan x="24" dy="22">gingTransport {</tspan></text>
<text x="24" y="4544" 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="4566" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># DEFAULT_DRAIN_DEADLINE 이라는 이름을 가진 선언과 그 사용처</tspan></text>
<text x="24" y="4588" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-outbox-jdbc-postgresql · main · OutboxRelayWorker.java:35 public static final Duration DEFAULT_DRAIN_</tspan><tspan x="24" dy="22">DEADLINE = Duration.ofSeconds(30);</tspan></text>
<text x="24" y="4632" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-outbox-jdbc-postgresql · main · OutboxRelayWorker.java:129 stop(DEFAULT_DRAIN_DEADLINE);</tspan></text>
<text x="24" y="4654" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-transport-spi · main · DefaultMessagingRuntimeRegistry.java:28 private static final Duration DEFAULT_</tspan><tspan x="24" dy="22">DRAIN_DEADLINE = Duration.ofSeconds(30);</tspan></text>
<text x="24" y="4698" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-transport-spi · main · DefaultMessagingRuntimeRegistry.java:36 this(DEFAULT_DRAIN_DEADLINE);</tspan></text>
<text x="24" y="4720" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-transport-spi · main · MessagingLifecycle.java:40 Duration DEFAULT_DRAIN_DEADLINE = Duration.ofSecond</tspan><tspan x="24" dy="22">s(30);</tspan></text>
<text x="24" y="4764" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-transport-spi · test · MessagingLifecycleTest.java:57 assertThat(MessagingLifecycle.DEFAULT_DRAIN_D</tspan><tspan x="24" dy="22">EADLINE).isEqualTo(Duration.ofSeconds(30));</tspan></text>
<text x="24" y="4808" 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="4830" 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="4852" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-spring-boot-starter · main · MessagingCoreAutoConfiguration.java:192 return new DefaultMessagingRun</tspan><tspan x="24" dy="22">timeRegistry(properties.getShutdown().getDrainDeadline());</tspan></text>
<text x="24" y="4896" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-spring-boot-starter · main · MessagingCoreAutoConfiguration.java:204 return new GracefulShutdownCoo</tspan><tspan x="24" dy="22">rdinator(properties.getShutdown().getDrainDeadline());</tspan></text>
<text x="24" y="4940" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-spring-boot-starter · main · MessagingCoreAutoConfiguration.java:243 admission, drain, properti</tspan><tspan x="24" dy="22">es.getShutdown().getDrainDeadline());</tspan></text>
<text x="24" y="4984" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-spring-boot-starter · main · MessagingSettings.java:281 private Duration drainDeadline = Duration.o</tspan><tspan x="24" dy="22">fSeconds(30);</tspan></text>
<text x="24" y="5028" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-spring-boot-starter · test · MessagingAutoConfigurationTest.java:83 assertThat(properties</tspan><tspan x="24" dy="22">.getShutdown().getDrainDeadline())</tspan></text>
<text x="24" y="5072" 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="5094" 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="5116" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-spring-boot-starter · main · MessagingOutboxRelayLifecycle.java:23 public final class MessagingOutboxRe</tspan><tspan x="24" dy="22">layLifecycle implements SmartLifecycle {</tspan></text>
<text x="24" y="5160" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-spring-boot-starter · main · MessagingShutdownLifecycle.java:30 public final class MessagingShutdownLif</tspan><tspan x="24" dy="22">ecycle implements SmartLifecycle {</tspan></text>
<text x="24" y="5204" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-spring-boot-starter · test · MessagingOutboxRelayLifecycleTest.java:38 class MessagingOutboxRelayLifecy</tspan><tspan x="24" dy="22">cleTest {</tspan></text>
<text x="24" y="5248" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> messaging/messaging-spring-boot-starter · test · MessagingShutdownLifecycleTest.java:25 class MessagingShutdownLifecycleTes</tspan><tspan x="24" dy="22">t {</tspan></text>
<text x="24" y="5292" 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="5314" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 열거형 상수 순서를 바꾸면 무엇이 깨지는가 (레포 사본을 /tmp 에서 컴파일)</tspan></text>
<text x="24" y="5336" 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="5358" 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="5380" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> CLOSE_CONNECTIONS 를 첫 상수로 옮겼을 때</tspan></text>
<text x="24" y="5402" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 통과 3 · 실패 3</tspan></text>
<text x="24" y="5424" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 깨진 시험 : connectionsCloseLastOfAll</tspan></text>
<text x="24" y="5446" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 깨진 시험 : outboxLeasesAreReleasedBeforeClosing</tspan></text>
<text x="24" y="5468" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 깨진 시험 : producerConfirmsAreAwaitedBeforeTheConnectionGoesAway</tspan></text>
<text x="24" y="5490" 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>
</svg>