@@ -28,6 +28,7 @@ public final class POSCatalogFullSyncService: POSCatalogFullSyncServiceProtocol
2828 private let syncRemote : POSCatalogSyncRemoteProtocol
2929 private let batchSize : Int
3030 private let persistenceService : POSCatalogPersistenceServiceProtocol
31+ private let batchedLoader : BatchedRequestLoader
3132
3233 public convenience init ? ( credentials: Credentials ? , batchSize: Int = 2 , grdbManager: GRDBManagerProtocol ) {
3334 guard let credentials else {
@@ -44,6 +45,7 @@ public final class POSCatalogFullSyncService: POSCatalogFullSyncServiceProtocol
4445 self . syncRemote = syncRemote
4546 self . batchSize = batchSize
4647 self . persistenceService = persistenceService
48+ self . batchedLoader = BatchedRequestLoader ( batchSize: batchSize)
4749 }
4850
4951 // MARK: - Protocol Conformance
@@ -73,95 +75,19 @@ public final class POSCatalogFullSyncService: POSCatalogFullSyncServiceProtocol
7375private extension POSCatalogFullSyncService {
7476 func loadCatalog( for siteID: Int64 , syncRemote: POSCatalogSyncRemoteProtocol ) async throws -> POSCatalog {
7577 // Loads products and variations in batches in parallel.
76- async let productsTask = loadAllProducts ( for: siteID, syncRemote: syncRemote)
77- async let variationsTask = loadAllProductVariations ( for: siteID, syncRemote: syncRemote)
78-
79- let ( products, variations) = try await ( productsTask, variationsTask)
80- return POSCatalog ( products: products, variations: variations)
81- }
82-
83- func loadAllProducts( for siteID: Int64 , syncRemote: POSCatalogSyncRemoteProtocol ) async throws -> [ POSProduct ] {
84- DDLogInfo ( " 🔄 Starting products sync for site ID: \( siteID) " )
85-
86- var allProducts : [ POSProduct ] = [ ]
87- var currentPage = 1
88- var hasMorePages = true
89-
90- while hasMorePages {
91- let pagesToFetch = Array ( currentPage..< ( currentPage + batchSize) )
92-
93- let batchResults = try await withThrowingTaskGroup ( of: PageResult< POSProduct> . self ) { group in
94- for pageNumber in pagesToFetch {
95- group. addTask {
96- let result = try await syncRemote. loadProducts ( siteID: siteID, pageNumber: pageNumber)
97- return PageResult ( pageNumber: pageNumber, items: result)
98- }
99- }
100-
101- var results : [ PageResult < POSProduct > ] = [ ]
102- for try await result in group {
103- results. append ( result)
104- }
105- return results. sorted ( by: { $0. pageNumber < $1. pageNumber } )
78+ async let productsTask = batchedLoader. loadAll (
79+ makeRequest: { pageNumber in
80+ try await syncRemote. loadProducts ( siteID: siteID, pageNumber: pageNumber)
10681 }
107-
108- // Processes results in order and checks if there are more pages.
109- let newProducts = batchResults. flatMap { $0. items. items }
110- allProducts. append ( contentsOf: newProducts)
111-
112- let highestPageResult = batchResults. last? . items
113- hasMorePages = ( highestPageResult? . hasMorePages ?? false ) && !newProducts. isEmpty
114- currentPage += batchSize
115-
116- DDLogInfo ( " 📥 Loaded batch: \( batchResults. count) pages, total products: \( allProducts. count) , hasMorePages: \( hasMorePages) " )
117- }
118-
119- DDLogInfo ( " ✅ Products sync complete: \( allProducts. count) products loaded " )
120- return allProducts
121- }
122-
123- func loadAllProductVariations( for siteID: Int64 , syncRemote: POSCatalogSyncRemoteProtocol ) async throws -> [ POSProductVariation ] {
124- DDLogInfo ( " 🔄 Starting variations sync for site ID: \( siteID) " )
125-
126- var allVariations : [ POSProductVariation ] = [ ]
127- var currentPage = 1
128- var hasMorePages = true
129-
130- while hasMorePages {
131- let pagesToFetch = Array ( currentPage..< ( currentPage + batchSize) )
132-
133- let batchResults = try await withThrowingTaskGroup ( of: PageResult< POSProductVariation> . self ) { group in
134- for pageNumber in pagesToFetch {
135- group. addTask {
136- let result = try await syncRemote. loadProductVariations ( siteID: siteID, pageNumber: pageNumber)
137- return PageResult ( pageNumber: pageNumber, items: result)
138- }
139- }
140-
141- var results : [ PageResult < POSProductVariation > ] = [ ]
142- for try await result in group {
143- results. append ( result)
144- }
145- return results. sorted ( by: { $0. pageNumber < $1. pageNumber } )
82+ )
83+ async let variationsTask = batchedLoader. loadAll (
84+ makeRequest: { pageNumber in
85+ try await syncRemote. loadProductVariations ( siteID: siteID, pageNumber: pageNumber)
14686 }
87+ )
14788
148- // Processes results in order and checks if there are more pages.
149- let newVariations = batchResults. flatMap { $0. items. items }
150- allVariations. append ( contentsOf: newVariations)
151-
152- let highestPageResult = batchResults. last? . items
153- hasMorePages = ( highestPageResult? . hasMorePages ?? false ) && !newVariations. isEmpty
154- currentPage += batchSize
155-
156- DDLogInfo ( " 📥 Loaded batch: \( batchResults. count) pages, total variations: \( allVariations. count) , hasMorePages: \( hasMorePages) " )
157- }
158-
159- DDLogInfo ( " ✅ Variations sync complete: \( allVariations. count) variations loaded " )
160- return allVariations
89+ let ( products, variations) = try await ( productsTask, variationsTask)
90+ return POSCatalog ( products: products, variations: variations)
16191 }
162- }
16392
164- private struct PageResult < T> {
165- let pageNumber : Int
166- let items : PagedItems < T >
16793}
0 commit comments