diff --git a/LeStorage/ApiCallCollection.swift b/LeStorage/ApiCallCollection.swift index e6f90c3..1589243 100644 --- a/LeStorage/ApiCallCollection.swift +++ b/LeStorage/ApiCallCollection.swift @@ -46,7 +46,7 @@ actor ApiCallCollection: SomeCallCollection { fileprivate var _attemptLoops: Int = 0 /// Indicates if the collection is currently retrying ApiCalls - fileprivate var _isRescheduling: Bool = false + fileprivate var _isExecutingCalls: Bool = false fileprivate var _schedulingTask: Task<(), Never>? = nil @@ -140,7 +140,7 @@ actor ApiCallCollection: SomeCallCollection { /// Removes all objects in memory and deletes the JSON file func reset() { - self._isRescheduling = false + self._isExecutingCalls = false self.items.removeAll() do { @@ -157,11 +157,11 @@ actor ApiCallCollection: SomeCallCollection { self._attemptLoops = -1 self.rescheduleApiCallsIfNecessary() -// if self._schedulingTask != nil && self._attemptLoops > 2 { -// self._schedulingTask?.cancel() -// self._attemptLoops = -1 -// self.rescheduleApiCallsIfNecessary() -// } + if self._schedulingTask != nil && self._attemptLoops > 2 { + self._schedulingTask?.cancel() + self._attemptLoops = -1 + self.rescheduleApiCallsIfNecessary() + } } func rescheduleImmediately() { @@ -171,7 +171,7 @@ actor ApiCallCollection: SomeCallCollection { /// Reschedule API calls if necessary func rescheduleApiCallsIfNecessary() { - if self.items.isNotEmpty && !self._isRescheduling { + if self.items.isNotEmpty && !self._isExecutingCalls { self._schedulingTask = Task { await self._waitAndExecuteApiCalls() } @@ -182,15 +182,16 @@ actor ApiCallCollection: SomeCallCollection { fileprivate func _waitAndExecuteApiCalls() async { // Logger.log("\(T.resourceName()) > RESCHED") - guard !self._isRescheduling, StoreCenter.main.collectionsCanSynchronize else { return } + guard !self._isExecutingCalls, StoreCenter.main.collectionsCanSynchronize else { return } guard self.items.isNotEmpty else { return } - self._isRescheduling = true + self._isExecutingCalls = true self._attemptLoops += 1 await self._wait() +// Logger.log("\(T.resourceName()) > EXECUTE CALLS: \(self.items.count)") let batches = Dictionary(grouping: self.items, by: { $0.transactionId }) for batch in batches.values { @@ -209,7 +210,8 @@ actor ApiCallCollection: SomeCallCollection { } } - self._isRescheduling = false +// Logger.log("\(T.resourceName()) > EXECUTE CALLS ENDED !") + self._isExecutingCalls = false if self.items.isNotEmpty { await self._waitAndExecuteApiCalls() } @@ -229,6 +231,8 @@ actor ApiCallCollection: SomeCallCollection { /// Wait for an exponentionnaly long time depending on the number of attemps fileprivate func _wait() async { + guard self._attemptLoops > 0 else { return } + var seconds = self._attemptLoops if self._attemptLoops > 5 { let delay = pow(2, self._attemptLoops - 2) // starts at 16s @@ -313,7 +317,7 @@ actor ApiCallCollection: SomeCallCollection { } } - func executeBatch(_ batch: OperationBatch) async throws -> [OperationResult] { + func executeBatch(_ batch: OperationBatch) async throws { var apiCalls: [ApiCall] = [] let transactionId = Store.randomId() @@ -329,7 +333,9 @@ actor ApiCallCollection: SomeCallCollection { let call = try self.callForInstance(delete, method: .delete, transactionId: transactionId) apiCalls.append(call) } - return try await self._executeApiCalls(apiCalls) + self.rescheduleApiCallsIfNecessary() + +// return try await self._executeApiCalls(apiCalls) } fileprivate func _prepareAndSendGetCall(_ apiCall: ApiCall) async throws { @@ -346,6 +352,9 @@ actor ApiCallCollection: SomeCallCollection { /// Executes an API call /// For POST requests, potentially copies additional data coming from the server during the insert fileprivate func _executeApiCalls(_ apiCalls: [ApiCall]) async throws -> [OperationResult] { +// for call in apiCalls { +// Logger.log("execute call = \(call.id)") +// } let results = try await StoreCenter.main.execute(apiCalls: apiCalls) for result in results { switch result.status { diff --git a/LeStorage/Services.swift b/LeStorage/Services.swift index c79b541..c29ba61 100644 --- a/LeStorage/Services.swift +++ b/LeStorage/Services.swift @@ -308,7 +308,7 @@ public class Services { if let response = task.1 as? HTTPURLResponse { let statusCode = response.statusCode - print("\(debugURL) ended, status code = \(statusCode)") + print("\(String(describing: T.self))> \(debugURL) ended, status code = \(statusCode)") switch statusCode { case 200..<300: // success @@ -320,14 +320,10 @@ public class Services { switch result.status { case 200..<300: break - // if let data = result.data { - // successes.append(data) - // } - - // try await StoreCenter.main.deleteApiCallById(type: T.self, id: result.apiCallId) default: if let message = result.message { - print(message) + let type = String(describing: T.self) + print("\(type) - \(result.apiCallId): \(result.status) > \(message)") } rescheduleApiCalls = true break diff --git a/LeStorage/StoreCenter.swift b/LeStorage/StoreCenter.swift index 29a50f4..f258f9f 100644 --- a/LeStorage/StoreCenter.swift +++ b/LeStorage/StoreCenter.swift @@ -403,9 +403,9 @@ public class StoreCenter { && self.userIsAllowed() } - func sendOperationBatch(_ batch: OperationBatch) async throws -> [OperationResult] { + func sendOperationBatch(_ batch: OperationBatch) async throws { guard self._canSynchronise() else { - return [] + return } return try await self.apiCallCollection().executeBatch(batch) } diff --git a/LeStorage/StoredCollection+Sync.swift b/LeStorage/StoredCollection+Sync.swift index 1527835..dd267c8 100644 --- a/LeStorage/StoredCollection+Sync.swift +++ b/LeStorage/StoredCollection+Sync.swift @@ -218,12 +218,13 @@ extension StoredCollection: SomeSyncedCollection where T : SyncedStorable { fileprivate func _sendOperationBatch(_ batch: OperationBatch) { Task { do { - let success = try await StoreCenter.main.sendOperationBatch(batch) - for item in success { - if let data = item.data { - self.updateFromServerInstance(data) - } - } + try await StoreCenter.main.sendOperationBatch(batch) +// let success = try await StoreCenter.main.sendOperationBatch(batch) +// for item in success { +// if let data = item.data { +// self.updateFromServerInstance(data) +// } +// } } catch { Logger.error(error) }