mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-10 00:16:59 +00:00
perf: adopt CachingEventDecoder in Android, Desktop, and amy clients
Passes decoder = CachingEventDecoder() at all four NostrClient construction sites: the Android app pool (AppModules), the Android crawl client (buildCrawlClient — Event Sync / Cashu discovery, the duplicate-heaviest path), the desktop RelayConnectionManager, and amy's Context. Duplicate EVENT frames (14-57% of production traffic) now skip the full JSON re-parse; dispatch semantics unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018saXqYfAa3RvSJoDXK591R
This commit is contained in:
@@ -100,6 +100,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayLogger
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.stats.RelayReqStats
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.stats.RelayStats
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.CachingEventDecoder
|
||||
import com.vitorpamplona.quartz.nip03Timestamp.VerificationStateCache
|
||||
import com.vitorpamplona.quartz.nip03Timestamp.okhttp.OkHttpBitcoinExplorer
|
||||
import com.vitorpamplona.quartz.nip03Timestamp.ots.OtsBlockHeightCache
|
||||
@@ -499,8 +500,10 @@ class AppModules(
|
||||
OkHttpLnurlEndpointResolver(roleBasedHttpClientBuilder::okHttpClientForMoney)
|
||||
}
|
||||
|
||||
// Provides a relay pool
|
||||
val client: INostrClient = NostrClient(websocketBuilder, applicationIOScope)
|
||||
// Provides a relay pool. The caching decoder skips re-parsing EVENT frames
|
||||
// that arrive again via another subscription or relay (14-57% of frames in
|
||||
// production measurements).
|
||||
val client: INostrClient = NostrClient(websocketBuilder, applicationIOScope, CachingEventDecoder())
|
||||
|
||||
// Self-heals the "Tor Active but every circuit dead" state the lifecycle watchdogs can't
|
||||
// see (they only arm while Connecting). Watches Tor-routed relay outcomes and, when enough
|
||||
|
||||
+4
-2
@@ -112,6 +112,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.auth.EmptyIAuthStatus
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.auth.RelayAuthenticator
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.CachingEventDecoder
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions
|
||||
@@ -310,8 +311,9 @@ class AccountViewModel(
|
||||
// but uses a SupervisorJob so child failures are independent.
|
||||
val customScope = CoroutineScope(viewModelScope.coroutineContext + SupervisorJob())
|
||||
|
||||
// Provides a relay pool
|
||||
val newClient = NostrClient(Amethyst.instance.websocketBuilder, customScope)
|
||||
// Provides a relay pool. Crawls hit many relays with overlapping
|
||||
// filters, so the duplicate-frame decoder pays off most here.
|
||||
val newClient = NostrClient(Amethyst.instance.websocketBuilder, customScope, CachingEventDecoder())
|
||||
|
||||
// Authenticates with relays (registers itself with the client).
|
||||
RelayAuthenticator(
|
||||
|
||||
@@ -45,6 +45,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.publishAndConfirmDetailed
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.single.newSubId
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.CachingEventDecoder
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer
|
||||
@@ -115,6 +116,9 @@ class Context(
|
||||
val client: NostrClient =
|
||||
NostrClient(
|
||||
websocketBuilder = BasicOkHttpWebSocket.Builder { okhttp },
|
||||
// Skips re-parsing EVENT frames that arrive again via another
|
||||
// subscription or relay.
|
||||
decoder = CachingEventDecoder(),
|
||||
)
|
||||
|
||||
/**
|
||||
|
||||
+4
-1
@@ -25,6 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.RelayConnectionListener
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.single.IRelayClient
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.CachingEventDecoder
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.EventMessage
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.Message
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.commands.toRelay.Command
|
||||
@@ -56,7 +57,9 @@ data class RelayMetrics(
|
||||
open class RelayConnectionManager(
|
||||
websocketBuilder: WebsocketBuilder,
|
||||
) : RelayConnectionListener {
|
||||
private val _client = NostrClient(websocketBuilder)
|
||||
// The caching decoder skips re-parsing EVENT frames that arrive again via
|
||||
// another subscription or relay.
|
||||
private val _client = NostrClient(websocketBuilder, decoder = CachingEventDecoder())
|
||||
|
||||
/** Exposes the underlying INostrClient for subscription coordinators */
|
||||
val client: com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient get() = _client
|
||||
|
||||
Reference in New Issue
Block a user