Phases 2.1/2.2/2.3, 3.1/3.2, 4, 5.2, and 6 of the launch-optimization plan
land together because they share a single set of seams and a single
benchmark report.
* InProcessWebsocketBuilder + LaunchFixtureRelay wrap quartz's existing
InProcessWebSocket + NostrServer (with EmptyPolicy) so any test can
drive a NostrClient against an in-memory relay seeded with arbitrary
events. Roundtrip verified by LaunchFixtureRelayTest.
* LaunchFixture builds a deterministic 50-note synthetic home-feed
snapshot from a fixed RNG seed (kind:1 + author kind:0 + kind:3 +
kind:10002). A real-world JSONL artifact is a drop-in replacement.
* NoteCard gets a stable testTag + a CompositionLocal-backed
onPlaced hook. Production overhead is one composition-local read
plus one null check per placement (default
LocalNoteCardInstrumentation = null).
* LaunchMarkers records named markers against TimeSource.Monotonic.
LaunchScenario.coldBoot drives the AccountManager (ViewOnly path)
+ DesktopLocalCache + RelayConnectionManager + LocalRelayStore
stack against the fixture relay and reports t_account_logged_in,
t_first_event, t_n_events.
* LaunchBenchmark runs 2 warmup + 5 measured iterations, computes
min/q1/median/q3/max, atomically writes the report file, and is
skipped by default — opt in via AMETHYST_BENCH=true. Baseline +
post-fix snapshots committed under desktopApp/benchmarks/.
* SubscribeBeforeConnectTest proves NostrClient / RelayPool queue REQs
issued before connect() and flush them when the connection comes up.
The bootstrap-config subscription in Main.kt drops its
`connectedRelays.first { isNotEmpty() }` + 30s withTimeoutOrNull gate
on the strength of that invariant — the subscription now fires
eagerly and recovers when no relay ever connects instead of silently
giving up after 30s.
All 274 desktopApp tests pass. No flaky tests introduced.
1.8 KiB
Launch Benchmark
Single-JVM warm benchmark for the cold-boot critical path. See
desktopApp/plans/2026-06-17-feat-app-launch-optimization-plan.md
for the design.
Run
AMETHYST_BENCH=true ./gradlew :desktopApp:test \
--tests "*LaunchBenchmark.run" --rerun-tasks
Without the env var the test class skips itself silently so a normal
./gradlew :desktopApp:test stays fast.
Output
A per-git-sha report lands at
desktopApp/build/benchmarks/launch-<git-sha>.txt. The benchmark prints the
report to stdout and atomically writes the file via
Files.move(... ATOMIC_MOVE) so a killed run does not pollute the trend
data with partial content.
Reading the numbers
Each row reports n, min, q1, median, q3, max in milliseconds. The
benchmark drives the slim "non-Compose" cold-boot scenario:
AccountManager.loadSavedAccount → relay subscription via
InProcessWebsocketBuilder (fixture relay) → DesktopLocalCache.consume.
t_account_logged_in—AccountManager.accountStatereachesLoggedIn(isReadOnly=true).t_first_event— firstkind:1flows throughDesktopLocalCache.consume.t_n_events—nth (defaultn=10)kind:1flows through the cache.
Numbers are dominated by the harness floor (InProcessWebSocket channel
hops, fixture-server REQ matching, coroutine dispatcher schedule). They
are most useful as a regression guard for code already in the
exercised path; they do not approximate a real Skia/Swing first paint.
Layered Compose-driven and JVM-fork variants are tracked as deferred
follow-ups in the plan.
Snapshots committed here
baseline-main.txt— pre-Phase-5.2 baseline.with-phase5-fixes.txt— post-Phase-5.2 snapshot.
Diff manually with diff -u baseline-main.txt with-phase5-fixes.txt.