mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-08 23:54:39 +00:00
The previous commit guarded EOSERelayList with a lock, which put the wrong path under it. addOrUpdate runs on **every live event** — SubscriptionListener.onEvent calls newEose for each one, hundreds per second across a few hundred relays — so that was one monitor for every event arriving in the app. Almost none of those events change the map. MutableTime exists precisely so a known relay only bumps a Long inside its own entry; the map is structurally written on the *first* frame from a relay, plus remove() and clear(). A couple of hundred writes for the lifetime of the process, against millions of reads. So the map is copy-on-write behind @Volatile: replaced wholesale under the lock, never mutated in place after publication. Readers take nothing. The per-event bump takes nothing. Only a relay's first frame pays, and it pays a map copy of a few hundred entries, once. The bump itself stays unsynchronized, which is deliberate: two socket threads racing updateIfNewer can leave the older timestamp, and this value is a floor for `since`, so losing a millisecond re-asks for a couple of events rather than skipping any. Documented on the method rather than fixed with an atomic that would cost a barrier per event. Verified: iOS, JVM, Android, desktop and the full suite build and pass. Cold start on emulator-5554 — no fatal exceptions, no ConcurrentModificationException, 0 nos.lol refusals, 182 relays connected and the purpose breakdown populated. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>