commit da2bdad18d1ddc3f2bde40dcb16aca6677fd681c
parent c7cc8df5bac5a64eb7468bae8c3e798c981fc12f
Author: William Casarin <jb55@jb55.com>
Date: Mon, 11 Dec 2023 12:44:40 -0800
nostrdb: close database when backgrounded
Otherwise iOS gets mad because we are holding onto a lockfile in a
shared container which is apparently not allowed.
Fixes: a1e6be214e41 ("Migrate NostrDB files to shared app group file container")
Diffstat:
3 files changed, 67 insertions(+), 8 deletions(-)
diff --git a/damus/ContentView.swift b/damus/ContentView.swift
@@ -448,18 +448,25 @@ struct ContentView: View {
break
}
}
+ .onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { obj in
+ print("📙 DAMUS ACTIVE NOTIFY")
+ try? damus_state.ndb.reopen()
+ }
.onChange(of: scenePhase) { (phase: ScenePhase) in
+ guard let damus_state else { return }
switch phase {
case .background:
print("📙 DAMUS BACKGROUNDED")
+ Task { @MainActor in
+ damus_state.ndb.close()
+ }
break
case .inactive:
print("📙 DAMUS INACTIVE")
break
case .active:
print("📙 DAMUS ACTIVE")
- guard let ds = damus_state else { return }
- ds.pool.ping()
+ damus_state.pool.ping()
@unknown default:
break
}
diff --git a/nostrdb/Ndb.swift b/nostrdb/Ndb.swift
@@ -15,8 +15,23 @@ enum NdbSearchOrder {
case newest_first
}
+
+enum DatabaseError: Error {
+ case failed_open
+
+ var errorDescription: String? {
+ switch self {
+ case .failed_open:
+ return "Failed to open database"
+ }
+ }
+}
+
class Ndb {
- let ndb: ndb_t
+ var ndb: ndb_t
+ let path: String?
+ let owns_db: Bool
+ var closed: Bool
static func safemode() -> Ndb? {
guard let path = db_path ?? old_db_path else { return nil }
@@ -58,8 +73,8 @@ class Ndb {
static var empty: Ndb {
Ndb(ndb: ndb_t(ndb: nil))
}
-
- init?(path: String? = nil, owns_db_file: Bool = true) {
+
+ static func open(path: String? = nil, owns_db_file: Bool = true) -> ndb_t? {
var ndb_p: OpaquePointer? = nil
let ingest_threads: Int32 = 4
@@ -102,7 +117,18 @@ class Ndb {
return nil
}
- self.ndb = ndb_t(ndb: ndb_p)
+ return ndb_t(ndb: ndb_p)
+ }
+
+ init?(path: String? = nil, owns_db_file: Bool = true) {
+ guard let db = Self.open(path: path, owns_db_file: owns_db_file) else {
+ return nil
+ }
+
+ self.path = path
+ self.owns_db = owns_db_file
+ self.ndb = db
+ self.closed = false
}
private static func migrate_db_location_if_needed() throws {
@@ -144,6 +170,23 @@ class Ndb {
init(ndb: ndb_t) {
self.ndb = ndb
+ self.path = nil
+ self.owns_db = true
+ self.closed = false
+ }
+
+ func close() {
+ self.closed = true
+ ndb_destroy(self.ndb.ndb)
+ }
+
+ func reopen() throws {
+ guard self.closed,
+ let db = Self.open(path: self.path, owns_db_file: self.owns_db) else {
+ throw DatabaseError.failed_open
+ }
+
+ self.ndb = db
}
func lookup_note_by_key_with_txn<Y>(_ key: NoteKey, txn: NdbTxn<Y>) -> NdbNote? {
@@ -344,12 +387,14 @@ class Ndb {
}
func process_event(_ str: String) -> Bool {
+ guard !closed else { return false }
return str.withCString { cstr in
return ndb_process_event(ndb.ndb, cstr, Int32(str.utf8.count)) != 0
}
}
func process_events(_ str: String) -> Bool {
+ guard !closed else { return false }
return str.withCString { cstr in
return ndb_process_events(ndb.ndb, cstr, str.utf8.count) != 0
}
@@ -387,7 +432,7 @@ class Ndb {
}
deinit {
- ndb_destroy(ndb.ndb)
+ self.close()
}
}
diff --git a/nostrdb/NdbTxn.swift b/nostrdb/NdbTxn.swift
@@ -29,7 +29,14 @@ class NdbTxn<T> {
self.inherited = true
} else {
self.txn = ndb_txn()
- let _ = ndb_begin_query(ndb.ndb.ndb, &self.txn)
+ let ok = ndb_begin_query(ndb.ndb.ndb, &self.txn) != 0
+ if !ok {
+ self.moved = false
+ self.txn = ndb_txn()
+ self.inherited = true
+ self.val = with(self)
+ return
+ }
Thread.current.threadDictionary["ndb_txn"] = self.txn
self.inherited = false
}