Merge pull request #3019 from vitorpamplona/claude/debug-metadata-relay-loading-opoto
Add fallback relay logic for abandoned users in metadata queries
This commit is contained in:
@@ -404,7 +404,7 @@ class Account(
|
||||
val dmRelays = DmInboxRelayState(dmRelayList, nip65RelayList, privateStorageRelayList, localRelayList, scope)
|
||||
val notificationRelays = NotificationInboxRelayState(nip65RelayList, localRelayList, scope)
|
||||
|
||||
val trustedRelays = TrustedRelayListsState(nip65RelayList, privateStorageRelayList, localRelayList, dmRelayList, searchRelayList, trustedRelayList, broadcastRelayList, scope)
|
||||
val trustedRelays = TrustedRelayListsState(nip65RelayList, privateStorageRelayList, localRelayList, dmRelayList, searchRelayList, indexerRelayList, proxyRelayList, trustedRelayList, broadcastRelayList, scope)
|
||||
|
||||
// Follows Relays
|
||||
val followOutboxesOrProxy = FollowListOutboxOrProxyRelays(kind3FollowList, blockedRelayList, proxyRelayList, cache, scope)
|
||||
|
||||
+10
@@ -24,6 +24,8 @@ import com.vitorpamplona.amethyst.model.edits.PrivateStorageRelayListState
|
||||
import com.vitorpamplona.amethyst.model.localRelays.LocalRelayListState
|
||||
import com.vitorpamplona.amethyst.model.nip17Dms.DmRelayListState
|
||||
import com.vitorpamplona.amethyst.model.nip51Lists.broadcastRelays.BroadcastRelayListState
|
||||
import com.vitorpamplona.amethyst.model.nip51Lists.indexerRelays.IndexerRelayListState
|
||||
import com.vitorpamplona.amethyst.model.nip51Lists.proxyRelays.ProxyRelayListState
|
||||
import com.vitorpamplona.amethyst.model.nip51Lists.searchRelays.SearchRelayListState
|
||||
import com.vitorpamplona.amethyst.model.nip51Lists.trustedRelays.TrustedRelayListState
|
||||
import com.vitorpamplona.amethyst.model.nip65RelayList.Nip65RelayListState
|
||||
@@ -43,6 +45,8 @@ class TrustedRelayListsState(
|
||||
val localRelayList: LocalRelayListState,
|
||||
val dmRelayList: DmRelayListState,
|
||||
val searchRelayListState: SearchRelayListState,
|
||||
val indexerRelayList: IndexerRelayListState,
|
||||
val proxyRelayList: ProxyRelayListState,
|
||||
val trustedRelayList: TrustedRelayListState,
|
||||
val broadcastRelayList: BroadcastRelayListState,
|
||||
val scope: CoroutineScope,
|
||||
@@ -57,6 +61,8 @@ class TrustedRelayListsState(
|
||||
localRelayList.flow,
|
||||
dmRelayList.flow,
|
||||
searchRelayListState.flowNoDefaults,
|
||||
indexerRelayList.flowNoDefaults,
|
||||
proxyRelayList.flow,
|
||||
trustedRelayList.flow,
|
||||
broadcastRelayList.flow,
|
||||
),
|
||||
@@ -70,6 +76,8 @@ class TrustedRelayListsState(
|
||||
localRelayList.flow.value,
|
||||
dmRelayList.flow.value,
|
||||
searchRelayListState.flowNoDefaults.value,
|
||||
indexerRelayList.flowNoDefaults.value,
|
||||
proxyRelayList.flow.value,
|
||||
trustedRelayList.flow.value,
|
||||
broadcastRelayList.flow.value,
|
||||
),
|
||||
@@ -86,6 +94,8 @@ class TrustedRelayListsState(
|
||||
localRelayList.flow.value,
|
||||
dmRelayList.flow.value,
|
||||
searchRelayListState.flowNoDefaults.value,
|
||||
indexerRelayList.flowNoDefaults.value,
|
||||
proxyRelayList.flow.value,
|
||||
trustedRelayList.flow.value,
|
||||
broadcastRelayList.flow.value,
|
||||
),
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ class UserFinderFilterAssembler(
|
||||
val group =
|
||||
listOf(
|
||||
UserOutboxFinderSubAssembler(client, cache, failureTracker, ::allKeys),
|
||||
UserWatcherSubAssembler(client, cache, ::allKeys),
|
||||
UserWatcherSubAssembler(client, cache, failureTracker, ::allKeys),
|
||||
UserReportsSubAssembler(client, cache, ::allKeys),
|
||||
UserCardsSubAssembler(client, cache, ::allKeys),
|
||||
)
|
||||
|
||||
+43
-10
@@ -20,12 +20,15 @@
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.loaders
|
||||
|
||||
import com.vitorpamplona.amethyst.commons.defaults.DefaultIndexerRelayList
|
||||
import com.vitorpamplona.amethyst.commons.defaults.DefaultSearchRelayList
|
||||
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.BaseEoseManager
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.follows.pickRelaysToLoadUsers
|
||||
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.UserFinderQueryState
|
||||
import com.vitorpamplona.amethyst.service.relays.EOSEAccountFast
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker
|
||||
@@ -107,16 +110,46 @@ class UserOutboxFinderSubAssembler(
|
||||
hasTried,
|
||||
)
|
||||
|
||||
return perRelayKeysBoth.mapNotNull {
|
||||
val sortedUsers = it.value.sorted()
|
||||
if (sortedUsers.isNotEmpty()) {
|
||||
RelayBasedFilter(
|
||||
relay = it.key,
|
||||
filter = Filter(kinds = relayListKinds, authors = sortedUsers),
|
||||
)
|
||||
} else {
|
||||
null
|
||||
val activeFilters =
|
||||
perRelayKeysBoth.mapNotNull {
|
||||
val sortedUsers = it.value.sorted()
|
||||
if (sortedUsers.isNotEmpty()) {
|
||||
RelayBasedFilter(
|
||||
relay = it.key,
|
||||
filter = Filter(kinds = relayListKinds, authors = sortedUsers),
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Users that pickRelaysToLoadUsers could not place anywhere this pass:
|
||||
// every candidate relay tier (outbox/hints/index/search/connected/common)
|
||||
// is already in hasTried. Without a fallback they'd be silently dropped
|
||||
// and a late-published kind 10002 would never reach the UI.
|
||||
val placedPubkeys =
|
||||
perRelayKeysBoth.values
|
||||
.asSequence()
|
||||
.flatten()
|
||||
.toSet()
|
||||
val abandonedPubkeys =
|
||||
noOutboxList.mapNotNullTo(mutableSetOf<HexKey>()) { user ->
|
||||
user.pubkeyHex.takeIf { it !in placedPubkeys }
|
||||
}
|
||||
|
||||
if (abandonedPubkeys.isEmpty()) return activeFilters
|
||||
|
||||
val sortedAbandoned = abandonedPubkeys.sorted()
|
||||
val fallbackRelays =
|
||||
(DefaultIndexerRelayList + DefaultSearchRelayList) - failureTracker.cannotConnectRelays
|
||||
val fallbackFilters =
|
||||
fallbackRelays.map { relay ->
|
||||
RelayBasedFilter(
|
||||
relay = relay,
|
||||
filter = Filter(kinds = relayListKinds, authors = sortedAbandoned),
|
||||
)
|
||||
}
|
||||
|
||||
return activeFilters + fallbackFilters
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -50,6 +50,7 @@ val UserMetadataForKeyKinds =
|
||||
fun filterUserMetadataForKey(
|
||||
authors: Set<User>,
|
||||
indexRelays: Set<NormalizedRelayUrl>,
|
||||
cannotConnectRelays: Set<NormalizedRelayUrl>,
|
||||
since: EOSEAccountFast<User>,
|
||||
): List<RelayBasedFilter> {
|
||||
val perRelayUsers =
|
||||
@@ -59,7 +60,7 @@ fun filterUserMetadataForKey(
|
||||
key.outboxRelays()
|
||||
?: (key.allUsedRelays() + LocalCache.relayHints.hintsForKey(key.pubkeyHex) + indexRelays)
|
||||
|
||||
relays.forEach {
|
||||
(relays - cannotConnectRelays).forEach {
|
||||
add(it, key)
|
||||
}
|
||||
}
|
||||
|
||||
+9
-1
@@ -28,6 +28,7 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.UserFinder
|
||||
import com.vitorpamplona.amethyst.service.relays.EOSEAccountFast
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.groupByRelay
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
@@ -37,6 +38,7 @@ import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
class UserWatcherSubAssembler(
|
||||
client: INostrClient,
|
||||
val cache: LocalCache,
|
||||
val failureTracker: RelayOfflineTracker,
|
||||
allKeys: () -> Set<UserFinderQueryState>,
|
||||
) : BaseEoseManager<UserFinderQueryState>(client, allKeys) {
|
||||
/**
|
||||
@@ -99,7 +101,13 @@ class UserWatcherSubAssembler(
|
||||
)
|
||||
}
|
||||
|
||||
val newFilters = filterUserMetadataForKey(users, indexRelays, latestEOSEs).ifEmpty { null }
|
||||
val newFilters =
|
||||
filterUserMetadataForKey(
|
||||
users,
|
||||
indexRelays,
|
||||
failureTracker.cannotConnectRelays,
|
||||
latestEOSEs,
|
||||
).ifEmpty { null }
|
||||
|
||||
sub.updateFilters(newFilters?.groupByRelay())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user