mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-30 07:37:38 +00:00
Default has one thread per core. With the number of coroutines the app
runs, any of them waiting on a lock (Note.syncLock, the quartz *Cache
classes, the Compose snapshot lock, relay-client maps), a store, a
signer or a log write can park enough of those threads to stall the
whole pool. Audited every explicit Dispatchers.Default site in quartz,
commons and commonsUI and moved the ones that can wait to IO:
- quartz: NostrSignerRemote and BleNostrClient scopes (decrypt via
SharedKeyCache, listener feeds the app cache), InProcessWebSocket
(drives RelaySession -> SQLite). ParallelEventVerifier now drains on
IO and evaluates preVerified + callbacks there; only event.verify()
fans out onto Default.
- commons: Cashu wallet/mint-directory cache indexing, WoTService writer
(snapshot lock), UserSearchEngine and SearchBarState cache scans,
PollResultsViewModel compute (User + mute checks), ChessLobbyLogic,
CallManager watchdog, RelaySpeedLogger, BootRelayDiagnostics, and
ImageReencoder's serial lane (file I/O).
- commonsUI: every LocalCache/Note/Account scan (calendars, minichat,
browser discover, software releases, concord pins, connected apps,
NIP-46 apps, active subscriptions, media prefetch), the lifecycle
unsubscribe grace scope, and BagSweep (up to two minutes of CPU on one
thread). Dropped ChannelNewMessageViewModel's Default wrapper around
PoWMiner.mine, which now picks its own threads.
Kept on Default only provably lock-free CPU: Schnorr verify (incl.
IngestQueue's hook), internal-key signing, hashing, HTML/JSON parsing,
rasterizing, and math over immutable lists.
Documents the rule in commons/ARCHITECTURE.md ("Choosing a dispatcher")
and the kotlin-coroutines skill.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TmGoCzsqVZYHZArjSCYBUa