diff --git a/damus/ContentView.swift b/damus/ContentView.swift index bc602512..da6121ea 100644 --- a/damus/ContentView.swift +++ b/damus/ContentView.swift @@ -538,9 +538,7 @@ struct ContentView: View { Log.debug("App background signal handling: App being backgrounded", for: .app_lifecycle) let startTime = CFAbsoluteTimeGetCurrent() await damus_state.nostrNetwork.handleAppBackgroundRequest() // Close ndb streaming tasks before closing ndb to avoid memory errors - Log.debug("App background signal handling: Nostr network closed after %.2f seconds", for: .app_lifecycle, CFAbsoluteTimeGetCurrent() - startTime) - damus_state.ndb.close() - Log.debug("App background signal handling: Ndb closed after %.2f seconds", for: .app_lifecycle, CFAbsoluteTimeGetCurrent() - startTime) + Log.debug("App background signal handling: Nostr network and Ndb closed after %.2f seconds", for: .app_lifecycle, CFAbsoluteTimeGetCurrent() - startTime) this_app.endBackgroundTask(bgTask) } break @@ -552,9 +550,7 @@ struct ContentView: View { Task { await damusClosingTask?.value // Wait for the closing task to finish before reopening things, to avoid race conditions damusClosingTask = nil - damus_state.ndb.reopen() - // Pinging the network will automatically reconnect any dead websocket connections - await damus_state.nostrNetwork.ping() + await damus_state.nostrNetwork.handleAppForegroundRequest() } @unknown default: break @@ -1144,7 +1140,6 @@ extension LossyLocalNotification { } } - func logout(_ state: DamusState?) { state?.close() diff --git a/damus/Core/Networking/NostrNetworkManager/NostrNetworkManager.swift b/damus/Core/Networking/NostrNetworkManager/NostrNetworkManager.swift index 6bc1a17f..69b61fe8 100644 --- a/damus/Core/Networking/NostrNetworkManager/NostrNetworkManager.swift +++ b/damus/Core/Networking/NostrNetworkManager/NostrNetworkManager.swift @@ -59,9 +59,19 @@ class NostrNetworkManager { await self.pool.disconnect() } - func handleAppBackgroundRequest() async { + func handleAppBackgroundRequest(beforeClosingNdb operationBeforeClosingNdb: (() async -> Void)? = nil) async { + // Mark NDB as closed without actually closing it, to avoid new tasks from using NostrDB + // self.delegate.ndb.markClosed() await self.reader.cancelAllTasks() await self.pool.cleanQueuedRequestForSessionEnd() + await operationBeforeClosingNdb?() + self.delegate.ndb.close() + } + + func handleAppForegroundRequest() async { + self.delegate.ndb.reopen() + // Pinging the network will automatically reconnect any dead websocket connections + await self.ping() } func close() async { diff --git a/nostrdb/Ndb.swift b/nostrdb/Ndb.swift index b171559d..97347658 100644 --- a/nostrdb/Ndb.swift +++ b/nostrdb/Ndb.swift @@ -207,6 +207,12 @@ class Ndb { self.callbackHandler = Ndb.CallbackHandler() } + /// Mark NostrDB as "closed" without actually closing it. + /// Useful when shutting down tasks that use NostrDB while avoiding new tasks from using it. + func markClosed() { + self.closed = true + } + func close() { guard !self.is_closed else { return } self.closed = true