diff --git a/Account/Sources/Account/Account.swift b/Account/Sources/Account/Account.swift index 94c1ae043..bce8940f2 100644 --- a/Account/Sources/Account/Account.swift +++ b/Account/Sources/Account/Account.swift @@ -695,6 +695,20 @@ public enum FetchType { } } + @MainActor public func asyncFetchArticles(_ fetchType: FetchType) async throws -> Set
{ + // Temporary until we can go async await all the way down. + return try await withCheckedThrowingContinuation { continuation in + fetchArticlesAsync(fetchType) { articleSetResult in + switch articleSetResult { + case .success(let articles): + continuation.resume(returning: articles) + case .failure(let error): + continuation.resume(throwing: error) + } + } + } + } + public func fetchArticlesAsync(_ fetchType: FetchType, _ completion: @escaping ArticleSetResultBlock) { switch fetchType { case .starred(let limit): @@ -1113,6 +1127,12 @@ private extension Account { } } + @MainActor func articlesForFeed(_ feed: Feed) async throws -> Set
{ + let articles = try await database.articlesForFeed(feed.feedID) + validateUnreadCount(feed, articles) + return articles + } + func fetchArticlesMatching(_ searchString: String) throws -> Set
{ return try database.fetchArticlesMatching(searchString, flattenedFeeds().feedIDs()) } diff --git a/Account/Sources/Account/AccountManager.swift b/Account/Sources/Account/AccountManager.swift index a6d488e80..ee29869dd 100644 --- a/Account/Sources/Account/AccountManager.swift +++ b/Account/Sources/Account/AccountManager.swift @@ -380,6 +380,33 @@ import RSDatabase // These fetch articles from active accounts and return a merged Set
. + @MainActor public func asyncFetchArticles(_ fetchType: FetchType) async throws -> Set
{ + + guard activeAccounts.count > 0 else { + return Set
() + } + + let articles = try await withThrowingTaskGroup(of: Set
.self) { taskGroup in + for account in activeAccounts { + taskGroup.addTask { + let articles = try await account.asyncFetchArticles(fetchType) + return articles + } + } + + var allFetchedArticles = Set
() + for try await oneAccountArticles in taskGroup { + allFetchedArticles.formUnion(oneAccountArticles) + } + + return allFetchedArticles + } + + return articles + } + + + @MainActor public func fetchArticles(_ fetchType: FetchType) throws -> Set
{ precondition(Thread.isMainThread) diff --git a/Account/Sources/Account/ArticleFetcher.swift b/Account/Sources/Account/ArticleFetcher.swift index 6e8e6e5f6..1d9196a06 100644 --- a/Account/Sources/Account/ArticleFetcher.swift +++ b/Account/Sources/Account/ArticleFetcher.swift @@ -17,6 +17,7 @@ import ArticlesDatabase func fetchUnreadArticles() throws -> Set
func fetchUnreadArticlesBetween(before: Date?, after: Date?) throws -> Set
func fetchUnreadArticlesAsync(_ completion: @escaping ArticleSetResultBlock) +// func asyncFetchUnreadArticles() async throws -> Set
} extension Feed: ArticleFetcher { @@ -57,6 +58,15 @@ extension Feed: ArticleFetcher { } } } + + public func asyncFetchUnreadArticles() async throws -> Set
{ + guard let account else { + assertionFailure("Expected feed.account, but got nil.") + return Set
() + } + let articles = try await account.asyncFetchArticles(.feed(self)) + return articles.unreadArticles() + } } extension Folder: ArticleFetcher { diff --git a/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesDatabase.swift b/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesDatabase.swift index 28e3e75a7..17ef2e2ea 100644 --- a/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesDatabase.swift +++ b/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesDatabase.swift @@ -136,7 +136,11 @@ public typealias ArticleStatusesResultBlock = (ArticleStatusesResult) -> Void // MARK: - Fetching Articles Async - public func fetchArticlesAsync(_ feedID: String, _ completion: @escaping ArticleSetResultBlock) { + public func articlesForFeed(_ feedID: String) async throws -> Set
{ + try await articlesTable.articlesForFeed(feedID) + } + + public func fetchArticlesAsync(_ feedID: String, _ completion: @escaping ArticleSetResultBlock) { articlesTable.fetchArticlesAsync(feedID, completion) } diff --git a/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesTable.swift b/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesTable.swift index c208ccf15..0b7800f7d 100644 --- a/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesTable.swift +++ b/ArticlesDatabase/Sources/ArticlesDatabase/ArticlesTable.swift @@ -47,7 +47,20 @@ final class ArticlesTable: DatabaseTable { } // MARK: - Fetching Articles for Feed - + + func articlesForFeed(_ feedID: String) async throws -> Set
{ + return try await withCheckedThrowingContinuation { continuation in + fetchArticlesAsync({ self.fetchArticlesForFeedID(feedID, $0) }) { articleSetResult in + switch articleSetResult { + case .success(let articles): + continuation.resume(returning: articles) + case .failure(let error): + continuation.resume(throwing: error) + } + } + } + } + func fetchArticles(_ feedID: String) throws -> Set
{ return try fetchArticles{ self.fetchArticlesForFeedID(feedID, $0) } }