Delete last completion-based method in SyncDatabase.

This commit is contained in:
Brent Simmons 2024-03-25 22:47:43 -07:00
parent c50ac0c84b
commit 4a5cb237a0
6 changed files with 79 additions and 117 deletions

View File

@ -69,11 +69,8 @@ class CloudKitSendStatusOperation: MainThreadOperation {
private extension CloudKitSendStatusOperation { private extension CloudKitSendStatusOperation {
func selectForProcessing() { func selectForProcessing() {
database.selectForProcessing(limit: blockSize) { result in
MainActor.assumeIsolated { Task { @MainActor in
switch result {
case .success(let syncStatuses):
@MainActor func stopProcessing() { @MainActor func stopProcessing() {
if self.showProgress { if self.showProgress {
@ -83,26 +80,25 @@ private extension CloudKitSendStatusOperation {
self.operationDelegate?.operationDidComplete(self) self.operationDelegate?.operationDidComplete(self)
} }
guard syncStatuses.count > 0 else { do {
guard let syncStatuses = try await self.database.selectForProcessing(limit: blockSize), !syncStatuses.isEmpty else {
stopProcessing() stopProcessing()
return return
} }
self.processStatuses(syncStatuses) { stop in self.processStatuses(Array(syncStatuses)) { stop in
if stop { if stop {
stopProcessing() stopProcessing()
} else { } else {
self.selectForProcessing() self.selectForProcessing()
} }
} }
} catch {
case .failure(let databaseError): os_log(.error, log: self.log, "Send status error: %@.", error.localizedDescription)
os_log(.error, log: self.log, "Send status error: %@.", databaseError.localizedDescription)
self.operationDelegate?.cancelOperation(self) self.operationDelegate?.cancelOperation(self)
} }
} }
} }
}
@MainActor func processStatuses(_ syncStatuses: [SyncStatus], completion: @escaping (Bool) -> Void) { @MainActor func processStatuses(_ syncStatuses: [SyncStatus], completion: @escaping (Bool) -> Void) {
guard let account = account, let articlesZone = articlesZone else { guard let account = account, let articlesZone = articlesZone else {

View File

@ -134,9 +134,12 @@ final class FeedbinAccountDelegate: AccountDelegate {
os_log(.debug, log: log, "Sending article statuses...") os_log(.debug, log: log, "Sending article statuses...")
database.selectForProcessing { result in Task { @MainActor in
do {
let syncStatuses = (try await self.database.selectForProcessing()) ?? Set<SyncStatus>()
MainActor.assumeIsolated {
@MainActor func processStatuses(_ syncStatuses: [SyncStatus]) { @MainActor func processStatuses(_ syncStatuses: [SyncStatus]) {
let createUnreadStatuses = syncStatuses.filter { $0.key == SyncStatus.Key.read && $0.flag == false } let createUnreadStatuses = syncStatuses.filter { $0.key == SyncStatus.Key.read && $0.flag == false }
let deleteUnreadStatuses = syncStatuses.filter { $0.key == SyncStatus.Key.read && $0.flag == true } let deleteUnreadStatuses = syncStatuses.filter { $0.key == SyncStatus.Key.read && $0.flag == true }
@ -188,12 +191,10 @@ final class FeedbinAccountDelegate: AccountDelegate {
} }
} }
switch result { processStatuses(Array(syncStatuses))
case .success(let syncStatuses):
processStatuses(syncStatuses) } catch {
case .failure(let databaseError): completion(.failure(error))
completion(.failure(databaseError))
}
} }
} }
} }

View File

@ -28,22 +28,16 @@ final class FeedlySendArticleStatusesOperation: FeedlyOperation {
override func run() { override func run() {
os_log(.debug, log: log, "Sending article statuses...") os_log(.debug, log: log, "Sending article statuses...")
database.selectForProcessing { result in Task { @MainActor in
MainActor.assumeIsolated {
if self.isCanceled {
self.didFinish()
return
}
switch result { do {
case .success(let syncStatuses): let syncStatuses = (try await self.database.selectForProcessing()) ?? Set<SyncStatus>()
self.processStatuses(syncStatuses) self.processStatuses(Array(syncStatuses))
case .failure: } catch {
self.didFinish() self.didFinish()
} }
} }
} }
}
} }
private extension FeedlySendArticleStatusesOperation { private extension FeedlySendArticleStatusesOperation {

View File

@ -134,9 +134,10 @@ final class NewsBlurAccountDelegate: AccountDelegate {
func sendArticleStatus(for account: Account, completion: @escaping (Result<Void, Error>) -> ()) { func sendArticleStatus(for account: Account, completion: @escaping (Result<Void, Error>) -> ()) {
os_log(.debug, log: log, "Sending story statuses...") os_log(.debug, log: log, "Sending story statuses...")
database.selectForProcessing { result in Task { @MainActor in
MainActor.assumeIsolated { do {
let syncStatuses = (try await self.database.selectForProcessing()) ?? Set<SyncStatus>()
@MainActor func processStatuses(_ syncStatuses: [SyncStatus]) { @MainActor func processStatuses(_ syncStatuses: [SyncStatus]) {
let createUnreadStatuses = syncStatuses.filter { let createUnreadStatuses = syncStatuses.filter {
@ -197,12 +198,9 @@ final class NewsBlurAccountDelegate: AccountDelegate {
} }
} }
switch result { processStatuses(Array(syncStatuses))
case .success(let syncStatuses): } catch {
processStatuses(syncStatuses) completion(.failure(error))
case .failure(let databaseError):
completion(.failure(databaseError))
}
} }
} }
} }

View File

@ -199,13 +199,17 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
} }
func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) { func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
os_log(.debug, log: log, "Sending article statuses...") os_log(.debug, log: log, "Sending article statuses...")
database.selectForProcessing { result in Task { @MainActor in
MainActor.assumeIsolated { do {
let syncStatuses = (try await self.database.selectForProcessing()) ?? Set<SyncStatus>()
@MainActor func processStatuses(_ syncStatuses: [SyncStatus]) { @MainActor func processStatuses(_ syncStatuses: [SyncStatus]) {
let createUnreadStatuses = syncStatuses.filter { $0.key == SyncStatus.Key.read && $0.flag == false } let createUnreadStatuses = syncStatuses.filter { $0.key == SyncStatus.Key.read && $0.flag == false }
let deleteUnreadStatuses = syncStatuses.filter { $0.key == SyncStatus.Key.read && $0.flag == true } let deleteUnreadStatuses = syncStatuses.filter { $0.key == SyncStatus.Key.read && $0.flag == true }
let createStarredStatuses = syncStatuses.filter { $0.key == SyncStatus.Key.starred && $0.flag == true } let createStarredStatuses = syncStatuses.filter { $0.key == SyncStatus.Key.starred && $0.flag == true }
@ -239,12 +243,9 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
} }
} }
switch result { processStatuses(Array(syncStatuses))
case .success(let syncStatuses): } catch {
processStatuses(syncStatuses) completion(.failure(error))
case .failure(let databaseError):
completion(.failure(databaseError))
}
} }
} }
} }

View File

@ -110,34 +110,6 @@ public actor SyncDatabase {
} }
} }
// MARK: - Compatibility
// Use the below until switching to the async version of the API.
public typealias SyncStatusesResult = Result<Array<SyncStatus>, DatabaseError>
public typealias SyncStatusesCompletionBlock = @Sendable (SyncStatusesResult) -> Void
public typealias SyncStatusArticleIDsResult = Result<Set<String>, DatabaseError>
public typealias SyncStatusArticleIDsCompletionBlock = @Sendable (SyncStatusArticleIDsResult) -> Void
public extension SyncDatabase {
nonisolated func selectForProcessing(limit: Int? = nil, completion: @escaping SyncStatusesCompletionBlock) {
Task { @MainActor in
do {
if let syncStatuses = try await self.selectForProcessing(limit: limit) {
completion(.success(Array(syncStatuses)))
} else {
completion(.success([SyncStatus]()))
}
} catch {
completion(.failure(DatabaseError.suspended))
}
}
}
}
private extension SyncDatabase { private extension SyncDatabase {
static let creationStatements = """ static let creationStatements = """