Improve transaction handling

pull/212/head
nielsandriesse 5 years ago
parent 7efc91b67a
commit 0683cbe952

@ -0,0 +1,19 @@
@objc public extension Storage {
// TODO: Add remaining collections
@objc func getDeviceLinkCollection(for masterPublicKey: String) -> String {
return "LokiDeviceLinkCollection-\(masterPublicKey)"
}
@objc public static func getSwarmCollection(for publicKey: String) -> String {
return "LokiSwarmCollection-\(publicKey)"
}
@objc public static let onionRequestPathCollection = "LokiOnionRequestPathCollection"
@objc public static let openGroupCollection = "LokiPublicChatCollection"
@objc public static let openGroupUserCountCollection = "LokiPublicChatUserCountCollection"
@objc public static let sessionRequestTimestampCollection = "LokiSessionRequestTimestampCollection"
@objc public static let snodePoolCollection = "LokiSnodePoolCollection"
}

@ -1,17 +1,23 @@
import PromiseKit
// Some important notes about YapDatabase:
//
// Connections are thread-safe.
// Executing a write transaction from within a write transaction is NOT allowed.
/// Some important notes about YapDatabase:
///
/// Connections are thread-safe.
/// Executing a write transaction from within a write transaction is NOT allowed.
@objc(LKStorage)
public final class Storage : NSObject {
private static let queue = DispatchQueue(label: "Storage.queue", qos: .userInitiated)
private static var owsStorage: OWSPrimaryStorage { OWSPrimaryStorage.shared() }
/// Some important points regarding reading from the database:
///
/// Background threads should use `OWSPrimaryStorage`'s `dbReadPool`, whereas the main thread should use `OWSPrimaryStorage`'s `uiDatabaseConnection` (see the `YapDatabaseConnectionPool` documentation for more information).
/// Multiple read transactions can safely be executed at the same time.
// MARK: Reading
// Some important points regarding reading from the database:
//
// Background threads should use `OWSPrimaryStorage`'s `dbReadConnection`, whereas the main thread should use `OWSPrimaryStorage`'s `uiDatabaseConnection` (see the `YapDatabaseConnectionPool` documentation for more information).
// Multiple read transactions can safely be executed at the same time.
@objc(readWithBlock:)
public static func read(with block: @escaping (YapDatabaseReadTransaction) -> Void) {
let isMainThread = Thread.current.isMainThread
@ -19,14 +25,35 @@ public final class Storage : NSObject {
connection.read(block)
}
/// Some important points regarding writing to the database:
///
/// There can only be a single write transaction per database at any one time, so all write transactions must use `OWSPrimaryStorage`'s `dbReadWriteConnection`.
/// Executing a write transaction from within a write transaction causes a deadlock and must be avoided.
// MARK: Writing
// Some important points regarding writing to the database:
//
// There can only be a single write transaction per database at any one time, so all write transactions must use `OWSPrimaryStorage`'s `dbReadWriteConnection`.
// Executing a write transaction from within a write transaction causes a deadlock and must be avoided.
@objc(writeWithBlock:)
public static func write(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void) {
// TODO: Right now this is kind of pointless, but the idea is to eventually
// somehow manage nested write transactions in this class.
public static func objc_write(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void) -> AnyPromise {
return AnyPromise.from(write(with: block))
}
public static func write(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void) -> Promise<Void> {
let (promise, seal) = Promise<Void>.pending()
queue.async { // TODO: There are cases where this isn't necessary
owsStorage.dbReadWriteConnection.readWrite(block)
seal.fulfill(())
}
return promise
}
/// Blocks the calling thread until the write has finished.
@objc(syncWriteWithBlock:error:)
public static func objc_syncWrite(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void) throws {
try syncWrite(with: block)
}
/// Blocks the calling thread until the write has finished.
public static func syncWrite(with block: @escaping (YapDatabaseReadWriteTransaction) -> Void) throws {
try write(with: block).wait()
}
}

Loading…
Cancel
Save