Skip to content

Commit 52bfb62

Browse files
authored
Merge pull request #5679 from wikimedia/dedupe-summary-requests
Activity tab - Dedupe in-flight summary requests
2 parents b895d20 + 0a3fc41 commit 52bfb62

File tree

3 files changed

+34
-9
lines changed

3 files changed

+34
-9
lines changed

WMFData/Sources/WMFData/Data Controllers/Saved Articles/WMFSavedArticlesDataController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public actor WMFSavedArticlesDataController {
1414
// MARK: - Lifecycle
1515

1616
public init(coreDataStore: WMFCoreDataStore? = WMFDataEnvironment.current.coreDataStore,
17-
articleSummaryDataController: WMFArticleSummaryDataController = .init()
17+
articleSummaryDataController: WMFArticleSummaryDataController = WMFArticleSummaryDataController.shared
1818
) {
1919
self._coreDataStore = coreDataStore
2020
self.articleSummaryDataController = articleSummaryDataController

WMFData/Sources/WMFData/Data Controllers/Shared/WMFArticleSummaryDataController.swift

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ public actor WMFArticleSummaryDataController: WMFArticleSummaryDataControlling {
1111
public static var shared = WMFArticleSummaryDataController()
1212

1313
private var cache: [WMFPage: WMFArticleSummary] = [:]
14+
private var inFlightRequests: [WMFPage: [(Result<WMFArticleSummary, Error>) -> Void]] = [:]
1415

15-
public init() {
16+
private init() {
1617
self.service = WMFDataEnvironment.current.basicService
1718
}
1819

@@ -24,14 +25,26 @@ public actor WMFArticleSummaryDataController: WMFArticleSummaryDataControlling {
2425
return
2526
}
2627

28+
// Check if there's already an in-flight request for this page
29+
if inFlightRequests[wmfPage] != nil {
30+
// Queue this completion to be called when the in-flight request completes
31+
inFlightRequests[wmfPage]?.append(completion)
32+
return
33+
}
34+
35+
// Initialize the in-flight request tracking with the first completion
36+
inFlightRequests[wmfPage] = [completion]
37+
2738
guard let service else {
28-
completion(.failure(WMFDataControllerError.basicServiceUnavailable))
39+
let error = WMFDataControllerError.basicServiceUnavailable
40+
resolveInFlightRequests(for: wmfPage, with: .failure(error))
2941
return
3042
}
3143

3244
guard !title.isEmpty,
3345
let url = URL.wikimediaRestAPIURL(project: project, additionalPathComponents: ["page", "summary", title.spacesToUnderscores]) else {
34-
completion(.failure(WMFDataControllerError.failureCreatingRequestURL))
46+
let error = WMFDataControllerError.failureCreatingRequestURL
47+
resolveInFlightRequests(for: wmfPage, with: .failure(error))
3548
return
3649
}
3750

@@ -43,20 +56,32 @@ public actor WMFArticleSummaryDataController: WMFArticleSummaryDataControlling {
4356
Task { [weak self] in
4457
guard let self else { return }
4558
await self.updateCache(page: wmfPage, summary: summary)
59+
await self.resolveInFlightRequests(for: wmfPage, with: result)
4660
}
4761

48-
default:
49-
break
62+
case .failure:
63+
Task { [weak self] in
64+
guard let self else { return }
65+
await self.resolveInFlightRequests(for: wmfPage, with: result)
66+
}
5067
}
51-
52-
completion(result)
5368
}
5469
}
5570

5671
private func updateCache(page: WMFPage, summary: WMFArticleSummary) {
5772
cache[page] = summary
5873
}
5974

75+
private func resolveInFlightRequests(for page: WMFPage, with result: Result<WMFArticleSummary, Error>) {
76+
guard let completions = inFlightRequests[page] else { return }
77+
inFlightRequests.removeValue(forKey: page)
78+
79+
// Call all waiting completions with the result
80+
for completion in completions {
81+
completion(result)
82+
}
83+
}
84+
6085
public func fetchArticleSummary(project: WMFProject, title: String) async throws -> WMFArticleSummary {
6186
return try await withCheckedThrowingContinuation { continuation in
6287
fetchArticleSummary(project: project, title: title) { result in

WMFData/Tests/WMFDataTests/WMFGrowthTasksDataControllerTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ final class WMFGrowthTasksDataControllerTests: XCTestCase {
8989

9090
func testFetchArticleSummary() async throws {
9191

92-
let controller = WMFArticleSummaryDataController()
92+
let controller = WMFArticleSummaryDataController.shared
9393

9494
let articleSummaryToTest = try await controller.fetchArticleSummary(project: csProject, title: "Novela (právo)")
9595

0 commit comments

Comments
 (0)