mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-09 08:04:45 +00:00
The per-relay pending maps in RelayLatencyTracker are Collections.synchronizedMap(LinkedHashMap): individual read/write ops are thread-safe, but per the synchronizedMap javadoc iteration is NOT — callers MUST hold the map's monitor while walking its views. sweep() was iterating directly, so any network-dispatcher mutation (adding a pending REQ, receiving an OK) during a sweep would throw ConcurrentModificationException on AWT-EventQueue-0, killing the Compose renderer while coroutine work kept running. Pre-existing bug, documented in memory desktop_relay_health_cme_crash. Ordinarily "not our problem", but it's actively blocking manual T3 testing of this branch's AUTH approval banner: adding any new relay triggers a RelayHealthStore.reclassify sweep, so testers can't get a banner render in without hitting the crash. Fix it here so the branch is actually testable end-to-end. Wrap both iteration loops in synchronized(pending) blocks. Sweep is O(pending) with typically single-digit entries per relay, so the hold time is negligible and the network dispatcher just briefly waits. Reproduced during manual T3 testing 2026-07-06 when adding wss://pyramid.fiatjaf.com. Stack: RelayLatencyTracker.sweep:182 → RelayHealthStore$reclassify$flagged$1.invokeSuspend:268.