@@ -4,36 +4,41 @@ import Storage
44import GRDB
55
66public protocol POSCatalogSyncCoordinatorProtocol {
7- /// Performs a full catalog sync for the specified site
8- /// - Parameter siteID: The site ID to sync catalog for
9- /// - Throws: POSCatalogSyncError.syncAlreadyInProgress if a sync is already running for this site
10- func performFullSync( for siteID: Int64 ) async throws
11-
12- /// Determines if a full sync should be performed based on the age of the last sync
7+ /// Performs a full catalog sync if applicable for the specified site
138 /// - Parameters:
14- /// - siteID: The site ID to check
9+ /// - siteID: The site ID to sync catalog for
1510 /// - maxAge: Maximum age before a sync is considered stale
16- /// - Returns: True if a sync should be performed
17- func shouldPerformFullSync ( for siteID: Int64 , maxAge: TimeInterval ) async -> Bool
11+ /// - Throws: POSCatalogSyncError.syncAlreadyInProgress if a sync is already running for this site
12+ func performFullSyncIfApplicable ( for siteID: Int64 , maxAge: TimeInterval ) async throws
1813
1914 /// Performs an incremental sync if applicable based on sync conditions
2015 /// - Parameters:
2116 /// - siteID: The site ID to sync catalog for
22- /// - forceSync: Whether to bypass age checks and always sync
17+ /// - maxAge: Maximum age before a sync is considered stale
2318 /// - Throws: POSCatalogSyncError.syncAlreadyInProgress if a sync is already running for this site
2419 //periphery:ignore - remove ignore comment when incremental sync is integrated with POS
25- func performIncrementalSyncIfApplicable( for siteID: Int64 , forceSync: Bool ) async throws
20+ func performIncrementalSyncIfApplicable( for siteID: Int64 , maxAge: TimeInterval ) async throws
21+ }
22+
23+ public extension POSCatalogSyncCoordinatorProtocol {
24+ func performFullSync( for siteID: Int64 ) async throws {
25+ try await performFullSyncIfApplicable ( for: siteID, maxAge: . zero)
26+ }
27+
28+ func performIncrementalSync( for siteID: Int64 ) async throws {
29+ try await performIncrementalSyncIfApplicable ( for: siteID, maxAge: . zero)
30+ }
2631}
2732
2833public enum POSCatalogSyncError : Error , Equatable {
2934 case syncAlreadyInProgress( siteID: Int64 )
35+ case negativeMaxAge
3036}
3137
3238public actor POSCatalogSyncCoordinator : POSCatalogSyncCoordinatorProtocol {
3339 private let fullSyncService : POSCatalogFullSyncServiceProtocol
3440 private let incrementalSyncService : POSCatalogIncrementalSyncServiceProtocol
3541 private let grdbManager : GRDBManagerProtocol
36- private let maxIncrementalSyncAge : TimeInterval
3742 private let catalogSizeLimit : Int
3843 private let catalogSizeChecker : POSCatalogSizeCheckerProtocol
3944
@@ -45,18 +50,24 @@ public actor POSCatalogSyncCoordinator: POSCatalogSyncCoordinatorProtocol {
4550 public init ( fullSyncService: POSCatalogFullSyncServiceProtocol ,
4651 incrementalSyncService: POSCatalogIncrementalSyncServiceProtocol ,
4752 grdbManager: GRDBManagerProtocol ,
48- maxIncrementalSyncAge: TimeInterval = 300 ,
4953 catalogSizeLimit: Int ? = nil ,
5054 catalogSizeChecker: POSCatalogSizeCheckerProtocol ) {
5155 self . fullSyncService = fullSyncService
5256 self . incrementalSyncService = incrementalSyncService
5357 self . grdbManager = grdbManager
54- self . maxIncrementalSyncAge = maxIncrementalSyncAge
5558 self . catalogSizeLimit = catalogSizeLimit ?? Constants . defaultSizeLimitForPOSCatalog
5659 self . catalogSizeChecker = catalogSizeChecker
5760 }
5861
59- public func performFullSync( for siteID: Int64 ) async throws {
62+ public func performFullSyncIfApplicable( for siteID: Int64 , maxAge: TimeInterval ) async throws {
63+ guard maxAge >= 0 else {
64+ throw POSCatalogSyncError . negativeMaxAge
65+ }
66+
67+ guard await shouldPerformFullSync ( for: siteID, maxAge: maxAge) else {
68+ return
69+ }
70+
6071 if ongoingSyncs. contains ( siteID) {
6172 DDLogInfo ( " ⚠️ POSCatalogSyncCoordinator: Sync already in progress for site \( siteID) " )
6273 throw POSCatalogSyncError . syncAlreadyInProgress ( siteID: siteID)
@@ -82,8 +93,8 @@ public actor POSCatalogSyncCoordinator: POSCatalogSyncCoordinatorProtocol {
8293 /// - siteID: The site ID to check
8394 /// - maxAge: Maximum age before a sync is considered stale
8495 /// - Returns: True if a sync should be performed
85- public func shouldPerformFullSync( for siteID: Int64 , maxAge: TimeInterval ) async -> Bool {
86- return await shouldPerformFullSync ( for: siteID, maxAge: maxAge, maxCatalogSize: catalogSizeLimit)
96+ private func shouldPerformFullSync( for siteID: Int64 , maxAge: TimeInterval ) async -> Bool {
97+ await shouldPerformFullSync ( for: siteID, maxAge: maxAge, maxCatalogSize: catalogSizeLimit)
8798 }
8899
89100 private func shouldPerformFullSync( for siteID: Int64 , maxAge: TimeInterval , maxCatalogSize: Int ) async -> Bool {
@@ -118,33 +129,28 @@ public actor POSCatalogSyncCoordinator: POSCatalogSyncCoordinatorProtocol {
118129 /// Performs an incremental sync if applicable based on sync conditions
119130 /// - Parameters:
120131 /// - siteID: The site ID to sync catalog for
121- /// - forceSync: Whether to bypass age checks and always sync
132+ /// - maxAge: Maximum age before a sync is considered stale
122133 /// - Throws: POSCatalogSyncError.syncAlreadyInProgress if a sync is already running for this site
123- public func performIncrementalSyncIfApplicable( for siteID: Int64 , forceSync : Bool ) async throws {
124- try await performIncrementalSyncIfApplicable ( for: siteID, forceSync : forceSync , maxCatalogSize: catalogSizeLimit)
134+ public func performIncrementalSyncIfApplicable( for siteID: Int64 , maxAge : TimeInterval ) async throws {
135+ try await performIncrementalSyncIfApplicable ( for: siteID, maxAge : maxAge , maxCatalogSize: catalogSizeLimit)
125136 }
126137
127- private func performIncrementalSyncIfApplicable( for siteID: Int64 , forceSync: Bool , maxCatalogSize: Int ) async throws {
128- if ongoingIncrementalSyncs. contains ( siteID) {
129- DDLogInfo ( " ⚠️ POSCatalogSyncCoordinator: Incremental sync already in progress for site \( siteID) " )
130- throw POSCatalogSyncError . syncAlreadyInProgress ( siteID: siteID)
138+ private func performIncrementalSyncIfApplicable( for siteID: Int64 , maxAge: TimeInterval , maxCatalogSize: Int ) async throws {
139+ guard maxAge >= 0 else {
140+ throw POSCatalogSyncError . negativeMaxAge
131141 }
132142
133- guard await isCatalogSizeWithinLimit ( for: siteID, maxCatalogSize: maxCatalogSize) else {
143+ guard await shouldPerformIncrementalSync ( for: siteID, maxAge : maxAge , maxCatalogSize: maxCatalogSize) else {
134144 return
135145 }
136146
137- guard let lastFullSyncDate = await lastFullSyncDate ( for : siteID) else {
138- DDLogInfo ( " 📋 POSCatalogSyncCoordinator: No full sync performed yet for site \( siteID) , skipping incremental sync " )
139- return
147+ if ongoingIncrementalSyncs . contains ( siteID) {
148+ DDLogInfo ( " ⚠️ POSCatalogSyncCoordinator: Incremental sync already in progress for site \( siteID) " )
149+ throw POSCatalogSyncError . syncAlreadyInProgress ( siteID : siteID )
140150 }
141151
142- if !forceSync, let lastIncrementalSyncDate = await lastIncrementalSyncDate ( for: siteID) {
143- let age = Date ( ) . timeIntervalSince ( lastIncrementalSyncDate)
144-
145- if age <= maxIncrementalSyncAge {
146- return DDLogInfo ( " 📋 POSCatalogSyncCoordinator: Last incremental sync for site \( siteID) was \( Int ( age) ) s ago, sync not needed " )
147- }
152+ guard let lastFullSyncDate = await lastFullSyncDate ( for: siteID) else {
153+ return
148154 }
149155
150156 ongoingIncrementalSyncs. insert ( siteID)
@@ -162,6 +168,28 @@ public actor POSCatalogSyncCoordinator: POSCatalogSyncCoordinatorProtocol {
162168 DDLogInfo ( " ✅ POSCatalogSyncCoordinator completed incremental sync for site \( siteID) " )
163169 }
164170
171+ private func shouldPerformIncrementalSync( for siteID: Int64 , maxAge: TimeInterval , maxCatalogSize: Int ) async -> Bool {
172+ guard await isCatalogSizeWithinLimit ( for: siteID, maxCatalogSize: maxCatalogSize) else {
173+ return false
174+ }
175+
176+ guard await lastFullSyncDate ( for: siteID) != nil else {
177+ DDLogInfo ( " 📋 POSCatalogSyncCoordinator: No full sync performed yet for site \( siteID) , skipping incremental sync " )
178+ return false
179+ }
180+
181+ if maxAge > 0 , let lastIncrementalSyncDate = await lastIncrementalSyncDate ( for: siteID) {
182+ let age = Date ( ) . timeIntervalSince ( lastIncrementalSyncDate)
183+
184+ if age <= maxAge {
185+ DDLogInfo ( " 📋 POSCatalogSyncCoordinator: Last incremental sync for site \( siteID) was \( Int ( age) ) s ago, sync not needed " )
186+ return false
187+ }
188+ }
189+
190+ return true
191+ }
192+
165193 // MARK: - Private
166194
167195 /// Checks if the catalog size is within the specified sync limit
0 commit comments