From 400a06f62b3fad351e95f19dfd25b348fb3cd7af Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 18 Jun 2026 19:04:22 +0000 Subject: [PATCH] revert(relay): leave RelayPool's connected set to onDisconnected Drops the _connectedRelays changes (the removeRelayInner prune and the derived-projection refresh) and restores RelayPool to match main. The incremental onConnected/onDisconnected maintenance is sufficient; the user-visible background relay-count issues are addressed by the lifecycle teardown timing and the notification-update throttle, not here. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01Ukw6FJPFh3JKGXL532p3ae --- .../nip01Core/relay/client/pool/RelayPool.kt | 28 ++----------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/RelayPool.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/RelayPool.kt index 9e46e81ba0..b60eda98a6 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/RelayPool.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/RelayPool.kt @@ -172,9 +172,6 @@ class RelayPool( if (atLeastOne) { _availableRelays.update { relays.keys() } - // Removed relays were just disconnected; reflect that in the connected set - // now rather than waiting for their (possibly dropped) onDisconnected callback. - refreshConnectedRelays() } } @@ -210,7 +207,6 @@ class RelayPool( fun removeRelay(relay: NormalizedRelayUrl) { if (removeRelayInner(relay)) { _availableRelays.update { relays.keys() } - refreshConnectedRelays() } } @@ -219,26 +215,6 @@ class RelayPool( disconnect() relays.clear() _availableRelays.update { emptySet() } - refreshConnectedRelays() - } - } - - /** - * Recomputes [_connectedRelays] from the source of truth: a relay is connected iff it - * is currently in the pool AND its socket reports ready ([IRelayClient.isConnected]). - * - * This is a pure projection of the pool rather than a set we add to / remove from on - * each event, so it cannot drift from reality. An incrementally maintained set goes - * stale whenever a state change isn't observed — e.g. OkHttp's async cancel() callback - * is dropped under mass teardown, or a socket dies without an onDisconnected — and then - * reports relays as connected that no longer are. Relays removed from the pool have - * already been disconnected (isConnected() == false), so they fall out here naturally. - */ - private fun refreshConnectedRelays() { - val connected = mutableSetOf() - relays.forEach { url, relay -> if (relay.isConnected()) connected.add(url) } - if (_connectedRelays.value != connected) { - _connectedRelays.value = connected } } @@ -252,12 +228,12 @@ class RelayPool( pingMillis: Int, compressed: Boolean, ) { - refreshConnectedRelays() + _connectedRelays.update { it + relay.url } listener.onConnected(relay, pingMillis, compressed) } override fun onDisconnected(relay: IRelayClient) { - refreshConnectedRelays() + _connectedRelays.update { it - relay.url } listener.onDisconnected(relay) }