Continue adopting async/await.

This commit is contained in:
Brent Simmons
2023-07-11 21:16:38 -07:00
parent 29cb574f3a
commit 65106be716
5 changed files with 178 additions and 209 deletions

View File

@@ -1268,87 +1268,63 @@ private extension FeedbinAccountDelegate {
}
func syncArticleReadState(account: Account, articleIDs: [Int]?, completion: @escaping (() -> Void)) {
guard let articleIDs = articleIDs else {
completion()
return
}
func syncArticleReadState(account: Account, articleIDs: [Int]?, completion: @escaping (() -> Void)) {
database.selectPendingReadStatusArticleIDs() { result in
func process(_ pendingArticleIDs: Set<String>) {
Task { @MainActor in
let feedbinUnreadArticleIDs = Set(articleIDs.map { String($0) } )
let updatableFeedbinUnreadArticleIDs = feedbinUnreadArticleIDs.subtracting(pendingArticleIDs)
do {
let currentUnreadArticleIDs = try await account.fetchUnreadArticleIDs()
// Mark articles as unread
let deltaUnreadArticleIDs = updatableFeedbinUnreadArticleIDs.subtracting(currentUnreadArticleIDs)
account.markAsUnread(deltaUnreadArticleIDs)
// Mark articles as read
let deltaReadArticleIDs = currentUnreadArticleIDs.subtracting(updatableFeedbinUnreadArticleIDs)
account.markAsRead(deltaReadArticleIDs)
} catch let error {
self.logger.error("Sync Articles Read Status failed: \(error.localizedDescription, privacy: .public)")
}
completion()
}
Task { @MainActor in
guard let articleIDs else {
completion()
return
}
switch result {
case .success(let pendingArticleIDs):
process(pendingArticleIDs)
case .failure(let error):
do {
let pendingArticleIDs = try await database.selectPendingReadArticleIDs()
let feedbinUnreadArticleIDs = Set(articleIDs.map { String($0) } )
let updatableFeedbinUnreadArticleIDs = feedbinUnreadArticleIDs.subtracting(pendingArticleIDs)
let currentUnreadArticleIDs = try await account.fetchUnreadArticleIDs()
// Mark articles as unread
let deltaUnreadArticleIDs = updatableFeedbinUnreadArticleIDs.subtracting(currentUnreadArticleIDs)
account.markAsUnread(deltaUnreadArticleIDs)
// Mark articles as read
let deltaReadArticleIDs = currentUnreadArticleIDs.subtracting(updatableFeedbinUnreadArticleIDs)
account.markAsRead(deltaReadArticleIDs)
} catch let error {
self.logger.error("Sync Articles Read Status failed: \(error.localizedDescription, privacy: .public)")
}
}
}
}
completion()
}
}
func syncArticleStarredState(account: Account, articleIDs: [Int]?, completion: @escaping (() -> Void)) {
guard let articleIDs = articleIDs else {
completion()
return
}
database.selectPendingStarredStatusArticleIDs() { result in
func process(_ pendingArticleIDs: Set<String>) {
Task { @MainActor in
let feedbinStarredArticleIDs = Set(articleIDs.map { String($0) } )
let updatableFeedbinStarredArticleIDs = feedbinStarredArticleIDs.subtracting(pendingArticleIDs)
do {
let currentStarredArticleIDs = try await account.fetchStarredArticleIDs()
// Mark articles as starred
let deltaStarredArticleIDs = updatableFeedbinStarredArticleIDs.subtracting(currentStarredArticleIDs)
account.markAsStarred(deltaStarredArticleIDs)
// Mark articles as unstarred
let deltaUnstarredArticleIDs = currentStarredArticleIDs.subtracting(updatableFeedbinStarredArticleIDs)
account.markAsUnstarred(deltaUnstarredArticleIDs)
} catch let error {
self.logger.error("Sync Article Starred Status failed: \(error.localizedDescription, privacy: .public)")
}
completion()
}
Task { @MainActor in
guard let articleIDs = articleIDs else {
completion()
return
}
switch result {
case .success(let pendingArticleIDs):
process(pendingArticleIDs)
case .failure(let error):
do {
let currentStarredArticleIDs = try await database.selectPendingStarredArticleIDs()
let feedbinStarredArticleIDs = Set(articleIDs.map { String($0) } )
let updatableFeedbinStarredArticleIDs = feedbinStarredArticleIDs.subtracting(currentStarredArticleIDs)
// Mark articles as starred
let deltaStarredArticleIDs = updatableFeedbinStarredArticleIDs.subtracting(currentStarredArticleIDs)
account.markAsStarred(deltaStarredArticleIDs)
// Mark articles as unstarred
let deltaUnstarredArticleIDs = currentStarredArticleIDs.subtracting(updatableFeedbinStarredArticleIDs)
account.markAsUnstarred(deltaUnstarredArticleIDs)
} catch let error {
self.logger.error("Sync Article Starred Status failed: \(error.localizedDescription, privacy: .public)")
}
completion()
}
}

View File

@@ -317,87 +317,68 @@ extension NewsBlurAccountDelegate {
}
func syncStoryReadState(account: Account, hashes: [NewsBlurStoryHash]?, completion: @escaping (() -> Void)) {
guard let hashes = hashes else {
completion()
return
}
database.selectPendingReadStatusArticleIDs() { result in
@MainActor func process(_ pendingStoryHashes: Set<String>) {
Task { @MainActor in
let newsBlurUnreadStoryHashes = Set(hashes.map { $0.hash } )
let updatableNewsBlurUnreadStoryHashes = newsBlurUnreadStoryHashes.subtracting(pendingStoryHashes)
do {
let currentUnreadArticleIDs = try await account.fetchUnreadArticleIDs()
// Mark articles as unread
let deltaUnreadArticleIDs = updatableNewsBlurUnreadStoryHashes.subtracting(currentUnreadArticleIDs)
account.markAsUnread(deltaUnreadArticleIDs)
// Mark articles as read
let deltaReadArticleIDs = currentUnreadArticleIDs.subtracting(updatableNewsBlurUnreadStoryHashes)
account.markAsRead(deltaReadArticleIDs)
} catch let error {
self.logger.error("Sync story read status failed: \(error.localizedDescription, privacy: .public)")
}
completion()
}
switch result {
case .success(let pendingArticleIDs):
process(pendingArticleIDs)
case .failure(let error):
self.logger.error("Sync story read status failed: \(error.localizedDescription, privacy: .public)")
}
Task { @MainActor in
guard let hashes = hashes else {
completion()
return
}
do {
let pendingStoryHashes = try await database.selectPendingReadArticleIDs()
let newsBlurUnreadStoryHashes = Set(hashes.map { $0.hash } )
let updatableNewsBlurUnreadStoryHashes = newsBlurUnreadStoryHashes.subtracting(pendingStoryHashes)
let currentUnreadArticleIDs = try await account.fetchUnreadArticleIDs()
// Mark articles as unread
let deltaUnreadArticleIDs = updatableNewsBlurUnreadStoryHashes.subtracting(currentUnreadArticleIDs)
account.markAsUnread(deltaUnreadArticleIDs)
// Mark articles as read
let deltaReadArticleIDs = currentUnreadArticleIDs.subtracting(updatableNewsBlurUnreadStoryHashes)
account.markAsRead(deltaReadArticleIDs)
} catch let error {
self.logger.error("Sync story read status failed: \(error.localizedDescription, privacy: .public)")
}
completion()
}
}
func syncStoryStarredState(account: Account, hashes: [NewsBlurStoryHash]?, completion: @escaping (() -> Void)) {
guard let hashes = hashes else {
completion()
return
}
func syncStoryStarredState(account: Account, hashes: [NewsBlurStoryHash]?, completion: @escaping (() -> Void)) {
database.selectPendingStarredStatusArticleIDs() { result in
func process(_ pendingStoryHashes: Set<String>) {
Task { @MainActor in
let newsBlurStarredStoryHashes = Set(hashes.map { $0.hash } )
let updatableNewsBlurUnreadStoryHashes = newsBlurStarredStoryHashes.subtracting(pendingStoryHashes)
do {
let currentStarredArticleIDs = try await account.fetchStarredArticleIDs()
// Mark articles as starred
let deltaStarredArticleIDs = updatableNewsBlurUnreadStoryHashes.subtracting(currentStarredArticleIDs)
account.markAsStarred(deltaStarredArticleIDs)
// Mark articles as unstarred
let deltaUnstarredArticleIDs = currentStarredArticleIDs.subtracting(updatableNewsBlurUnreadStoryHashes)
account.markAsUnstarred(deltaUnstarredArticleIDs)
} catch let error {
self.logger.error("Sync story starred status failed: \(error.localizedDescription, privacy: .public)")
}
completion()
}
Task { @MainActor in
guard let hashes = hashes else {
completion()
return
}
switch result {
case .success(let pendingArticleIDs):
process(pendingArticleIDs)
case .failure(let error):
self.logger.error("Sync story starred status failed: \(error.localizedDescription, privacy: .public)")
}
}
}
do {
let pendingStoryHashes = try await database.selectPendingStarredArticleIDs()
func createFeed(account: Account, newsBlurFeed: NewsBlurFeed?, name: String?, container: Container, completion: @escaping (Result<Feed, Error>) -> Void) {
let newsBlurStarredStoryHashes = Set(hashes.map { $0.hash } )
let updatableNewsBlurUnreadStoryHashes = newsBlurStarredStoryHashes.subtracting(pendingStoryHashes)
let currentStarredArticleIDs = try await account.fetchStarredArticleIDs()
// Mark articles as starred
let deltaStarredArticleIDs = updatableNewsBlurUnreadStoryHashes.subtracting(currentStarredArticleIDs)
account.markAsStarred(deltaStarredArticleIDs)
// Mark articles as unstarred
let deltaUnstarredArticleIDs = currentStarredArticleIDs.subtracting(updatableNewsBlurUnreadStoryHashes)
account.markAsUnstarred(deltaUnstarredArticleIDs)
} catch let error {
self.logger.error("Sync story starred status failed: \(error.localizedDescription, privacy: .public)")
}
completion()
}
}
func createFeed(account: Account, newsBlurFeed: NewsBlurFeed?, name: String?, container: Container, completion: @escaping (Result<Feed, Error>) -> Void) {
guard let newsBlurFeed = newsBlurFeed else {
completion(.failure(NewsBlurError.invalidParameter))
return

View File

@@ -1079,81 +1079,62 @@ private extension ReaderAPIAccountDelegate {
}
func syncArticleReadState(account: Account, articleIDs: [String]?, completion: @escaping (() -> Void)) {
guard let articleIDs = articleIDs else {
completion()
return
}
database.selectPendingReadStatusArticleIDs() { result in
@MainActor func process(_ pendingArticleIDs: Set<String>) {
Task { @MainActor in
let updatableReaderUnreadArticleIDs = Set(articleIDs).subtracting(pendingArticleIDs)
do {
let currentUnreadArticleIDs = try await account.fetchUnreadArticleIDs()
// Mark articles as unread
let deltaUnreadArticleIDs = updatableReaderUnreadArticleIDs.subtracting(currentUnreadArticleIDs)
account.markAsUnread(deltaUnreadArticleIDs)
// Mark articles as read
let deltaReadArticleIDs = currentUnreadArticleIDs.subtracting(updatableReaderUnreadArticleIDs)
account.markAsRead(deltaReadArticleIDs)
} catch let error {
self.logger.error("Sync Article Read Status failed: \(error.localizedDescription, privacy: .public)")
}
completion()
}
switch result {
case .success(let pendingArticleIDs):
process(pendingArticleIDs)
case .failure(let error):
self.logger.error("Sync Article Read Status failed: \(error.localizedDescription, privacy: .public)")
}
Task { @MainActor in
guard let articleIDs = articleIDs else {
completion()
return
}
do {
let pendingArticleIDs = try await database.selectPendingReadArticleIDs()
let updatableReaderUnreadArticleIDs = Set(articleIDs).subtracting(pendingArticleIDs)
let currentUnreadArticleIDs = try await account.fetchUnreadArticleIDs()
// Mark articles as unread
let deltaUnreadArticleIDs = updatableReaderUnreadArticleIDs.subtracting(currentUnreadArticleIDs)
account.markAsUnread(deltaUnreadArticleIDs)
// Mark articles as read
let deltaReadArticleIDs = currentUnreadArticleIDs.subtracting(updatableReaderUnreadArticleIDs)
account.markAsRead(deltaReadArticleIDs)
} catch let error {
self.logger.error("Sync Article Read Status failed: \(error.localizedDescription, privacy: .public)")
}
completion()
}
}
func syncArticleStarredState(account: Account, articleIDs: [String]?, completion: @escaping (() -> Void)) {
guard let articleIDs = articleIDs else {
completion()
return
}
database.selectPendingStarredStatusArticleIDs() { result in
func process(_ pendingArticleIDs: Set<String>) {
Task { @MainActor in
do {
let updatableReaderUnreadArticleIDs = Set(articleIDs).subtracting(pendingArticleIDs)
let currentStarredArticleIDs = try await account.fetchStarredArticleIDs()
// Mark articles as starred
let deltaStarredArticleIDs = updatableReaderUnreadArticleIDs.subtracting(currentStarredArticleIDs)
account.markAsStarred(deltaStarredArticleIDs)
// Mark articles as unstarred
let deltaUnstarredArticleIDs = currentStarredArticleIDs.subtracting(updatableReaderUnreadArticleIDs)
account.markAsUnstarred(deltaUnstarredArticleIDs)
} catch let error {
self.logger.error("Sync Article Starred Status failed: \(error.localizedDescription, privacy: .public)")
}
completion()
}
Task { @MainActor in
guard let articleIDs = articleIDs else {
completion()
return
}
switch result {
case .success(let pendingArticleIDs):
process(pendingArticleIDs)
case .failure(let error):
do {
let pendingArticleIDs = try await database.selectPendingStarredArticleIDs()
let updatableReaderUnreadArticleIDs = Set(articleIDs).subtracting(pendingArticleIDs)
let currentStarredArticleIDs = try await account.fetchStarredArticleIDs()
// Mark articles as starred
let deltaStarredArticleIDs = updatableReaderUnreadArticleIDs.subtracting(currentStarredArticleIDs)
account.markAsStarred(deltaStarredArticleIDs)
// Mark articles as unstarred
let deltaUnstarredArticleIDs = currentStarredArticleIDs.subtracting(updatableReaderUnreadArticleIDs)
account.markAsUnstarred(deltaUnstarredArticleIDs)
} catch let error {
self.logger.error("Sync Article Starred Status failed: \(error.localizedDescription, privacy: .public)")
}
completion()
}
}
}

View File

@@ -44,10 +44,18 @@ public struct SyncDatabase {
syncStatusTable.selectPendingCount(completion)
}
public func selectPendingReadArticleIDs() async throws -> Set<String> {
try await syncStatusTable.selectPendingReadArticleIDs()
}
public func selectPendingReadStatusArticleIDs(completion: @escaping SyncStatusArticleIDsCompletionBlock) {
syncStatusTable.selectPendingReadStatusArticleIDs(completion: completion)
}
public func selectPendingStarredArticleIDs() async throws -> Set<String> {
try await syncStatusTable.selectPendingStarredArticleIDs()
}
public func selectPendingStarredStatusArticleIDs(completion: @escaping SyncStatusArticleIDsCompletionBlock) {
syncStatusTable.selectPendingStarredStatusArticleIDs(completion: completion)
}

View File

@@ -87,10 +87,18 @@ struct SyncStatusTable: DatabaseTable {
}
}
func selectPendingReadArticleIDs() async throws -> Set<String> {
return try await selectPendingArticleIDs(.read)
}
func selectPendingReadStatusArticleIDs(completion: @escaping SyncStatusArticleIDsCompletionBlock) {
selectPendingArticleIDsAsync(.read, completion)
}
func selectPendingStarredArticleIDs() async throws -> Set<String> {
return try await selectPendingArticleIDs(.starred)
}
func selectPendingStarredStatusArticleIDs(completion: @escaping SyncStatusArticleIDsCompletionBlock) {
selectPendingArticleIDsAsync(.starred, completion)
}
@@ -197,7 +205,22 @@ private extension SyncStatusTable {
return SyncStatus(articleID: articleID, key: key, flag: flag, selected: selected)
}
func selectPendingArticleIDs(_ statusKey: ArticleStatus.Key) async throws -> Set<String> {
return try await withCheckedThrowingContinuation() { continuation in
Task { @MainActor in
selectPendingArticleIDsAsync(statusKey) { result in
switch result {
case .success(let articleIDs):
continuation.resume(returning: articleIDs)
case .failure(let databaseError):
continuation.resume(throwing: databaseError)
}
}
}
}
}
func selectPendingArticleIDsAsync(_ statusKey: ArticleStatus.Key, _ completion: @escaping SyncStatusArticleIDsCompletionBlock) {
queue.runInDatabase { databaseResult in