diff --git a/damus/Core/Networking/NostrNetworkManager/SubscriptionManager.swift b/damus/Core/Networking/NostrNetworkManager/SubscriptionManager.swift index aac1d922..7ea4cfb6 100644 --- a/damus/Core/Networking/NostrNetworkManager/SubscriptionManager.swift +++ b/damus/Core/Networking/NostrNetworkManager/SubscriptionManager.swift @@ -198,13 +198,6 @@ extension NostrNetworkManager { continue } - // FIXME: The delay below is to prevent race conditions when the RelayPool is initializing during the app start. - // Without this, occasionally there is a race condition that causes the subscribe call to be missed somehow - // despite mechanisms in place to queue up requests when relays are disconnected, as well as mechanisms to send subscribe requests when the relay is already connected. - // This is difficult to fix as it will require a big refactor in `RelayPool` to implement proper async/await mechanisms, instead of the current "fire and forget" interfaces. - // If this delay fixes the occasional timeline staleness when starting the app, it helps prove the hypothesis above. - try await Task.sleep(nanoseconds: 2_000_000_000) - do { for await item in self.pool.subscribe(filters: filters, to: desiredRelays, id: id) { // NO-OP. Notes will be automatically ingested by NostrDB diff --git a/damus/Core/Nostr/RelayPool.swift b/damus/Core/Nostr/RelayPool.swift index 96226d16..86705744 100644 --- a/damus/Core/Nostr/RelayPool.swift +++ b/damus/Core/Nostr/RelayPool.swift @@ -259,7 +259,7 @@ class RelayPool { /// - Returns: Returns an async stream that callers can easily consume via a for-loop func subscribe(filters: [NostrFilter], to desiredRelays: [RelayURL]? = nil, eoseTimeout: Duration? = nil, id: UUID? = nil) -> AsyncStream { let eoseTimeout = eoseTimeout ?? .seconds(5) - let desiredRelays = desiredRelays ?? self.relays.filter({ $0.connection.isConnected }).map({ $0.descriptor.url }) + let desiredRelays = desiredRelays ?? self.relays.map({ $0.descriptor.url }) let startTime = CFAbsoluteTimeGetCurrent() return AsyncStream { continuation in let id = id ?? UUID() @@ -284,8 +284,9 @@ class RelayPool { break // We do not support handling these yet case .eose(_): relaysWhoFinishedInitialResults.insert(relayUrl) - Log.debug("RelayPool subscription %s: EOSE from %s. EOSE count: %d/%d. Elapsed: %.2f seconds.", for: .networking, id.uuidString, relayUrl.absoluteString, relaysWhoFinishedInitialResults.count, Set(desiredRelays).count, CFAbsoluteTimeGetCurrent() - startTime) - if relaysWhoFinishedInitialResults == Set(desiredRelays) { + let desiredAndConnectedRelays = desiredRelays ?? self.relays.filter({ $0.connection.isConnected }).map({ $0.descriptor.url }) + Log.debug("RelayPool subscription %s: EOSE from %s. EOSE count: %d/%d. Elapsed: %.2f seconds.", for: .networking, id.uuidString, relayUrl.absoluteString, relaysWhoFinishedInitialResults.count, Set(desiredAndConnectedRelays).count, CFAbsoluteTimeGetCurrent() - startTime) + if relaysWhoFinishedInitialResults == Set(desiredAndConnectedRelays) { continuation.yield(with: .success(.eose)) eoseSent = true }