From d3431c0c555f4ed6ce1bd2c5ac557facb5f4ff2f Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 29 Nov 2024 15:53:19 +0100 Subject: [PATCH 1/6] add logs --- LeStorage/StoreCenter.swift | 3 +++ LeStorage/StoredCollection.swift | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/LeStorage/StoreCenter.swift b/LeStorage/StoreCenter.swift index 40e6106..3fe6302 100644 --- a/LeStorage/StoreCenter.swift +++ b/LeStorage/StoreCenter.swift @@ -378,6 +378,7 @@ public class StoreCenter { /// - instance: an object to insert func sendInsertion(_ instance: T) async throws -> T? { guard self._canSynchronise() else { + StoreCenter.main.log(message: "cannot send insert: \(T.resourceName()), \(StoreCenter.main.userName() ?? "no user")") return nil } return try await self.apiCallCollection().sendInsertion(instance) @@ -388,6 +389,7 @@ public class StoreCenter { /// - instance: an object to update func sendUpdate(_ instance: T) async throws -> T? { guard self._canSynchronise() else { + StoreCenter.main.log(message: "cannot send update: \(T.resourceName()), \(StoreCenter.main.userName() ?? "no user")") return nil } return try await self.apiCallCollection().sendUpdate(instance) @@ -398,6 +400,7 @@ public class StoreCenter { /// - instance: an object to delete func sendDeletion(_ instance: T) async throws { guard self._canSynchronise() else { + StoreCenter.main.log(message: "cannot send delete: \(T.resourceName()), \(StoreCenter.main.userName() ?? "no user")") return } try await self.apiCallCollection().sendDeletion(instance) diff --git a/LeStorage/StoredCollection.swift b/LeStorage/StoredCollection.swift index 4c6165d..e04650c 100644 --- a/LeStorage/StoredCollection.swift +++ b/LeStorage/StoredCollection.swift @@ -421,6 +421,7 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti /// - instance: the object to POST fileprivate func _sendInsertionIfNecessary(_ instance: T) { guard self.synchronized else { + StoreCenter.main.log(message: "cannot send insert: \(T.resourceName()), \(StoreCenter.main.userName() ?? "no user") : sync = \(self.synchronized)") return } Task { @@ -429,6 +430,7 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti self.updateFromServerInstance(result) } } catch { + StoreCenter.main.log(message: error.localizedDescription) Logger.error(error) } } @@ -450,12 +452,14 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti /// - instance: the object to PUT fileprivate func _sendUpdateIfNecessary(_ instance: T) { guard self.synchronized, self._sendsUpdate else { + StoreCenter.main.log(message: "cannot send update: \(T.resourceName()), \(StoreCenter.main.userName() ?? "no user") : sync = \(self.synchronized), self._sendsUpdate = \(self._sendsUpdate)") return } Task { do { try await self._store.sendUpdate(instance) } catch { + StoreCenter.main.log(message: error.localizedDescription) Logger.error(error) } } @@ -466,12 +470,14 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti /// - instance: the object to DELETE fileprivate func _sendDeletionIfNecessary(_ instance: T) { guard self.synchronized else { + StoreCenter.main.log(message: "cannot send delete: \(T.resourceName()), \(StoreCenter.main.userName() ?? "no user") : sync = \(self.synchronized)") return } Task { do { try await self._store.sendDeletion(instance) } catch { + StoreCenter.main.log(message: error.localizedDescription) Logger.error(error) } } From c32c01568bf6cf37b7b40f00e9339af319307271 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 2 Dec 2024 11:04:27 +0100 Subject: [PATCH 2/6] Adds limits for logs and failed api call + method to reset them --- LeStorage/Store.swift | 4 ++-- LeStorage/StoreCenter.swift | 19 +++++++++++++++++-- LeStorage/StoredCollection.swift | 14 +++++++++++++- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/LeStorage/Store.swift b/LeStorage/Store.swift index f023778..8cf84c5 100644 --- a/LeStorage/Store.swift +++ b/LeStorage/Store.swift @@ -88,9 +88,9 @@ open class Store { /// - indexed: Creates an index to quickly access the data /// - inMemory: Indicates if the collection should only live in memory, and not write into a file /// - sendsUpdate: Indicates if updates of items should be sent to the server - public func registerCollection(synchronized: Bool, indexed: Bool = false, inMemory: Bool = false, sendsUpdate: Bool = true) -> StoredCollection { + public func registerCollection(synchronized: Bool, indexed: Bool = false, inMemory: Bool = false, sendsUpdate: Bool = true, limit: Int? = nil) -> StoredCollection { - let collection = StoredCollection(synchronized: synchronized, store: self, indexed: indexed, inMemory: inMemory, sendsUpdate: sendsUpdate) + let collection = StoredCollection(synchronized: synchronized, store: self, indexed: indexed, inMemory: inMemory, sendsUpdate: sendsUpdate, limit: limit) self._collections[T.resourceName()] = collection if synchronized { diff --git a/LeStorage/StoreCenter.swift b/LeStorage/StoreCenter.swift index 3fe6302..3d351ef 100644 --- a/LeStorage/StoreCenter.swift +++ b/LeStorage/StoreCenter.swift @@ -251,6 +251,21 @@ public class StoreCenter { } } + public func resetLoggingCollections() { + self._failedAPICallsCollection?.reset() + self._logs?.reset() + Task { + do { + let facApiCallCollection: ApiCallCollection = try self.apiCallCollection() + await facApiCallCollection.reset() + let logApiCallCollection: ApiCallCollection = try self.apiCallCollection() + await logApiCallCollection.reset() + } catch { + Logger.error(error) + } + } + } + /// Resets the ApiCall whose type identifies with the provided collection /// - Parameters: /// - collection: The collection identifying the Storable type @@ -282,7 +297,7 @@ public class StoreCenter { /// This method triggers the framework to save and send failed api calls public func logsFailedAPICalls() { - self._failedAPICallsCollection = Store.main.registerCollection(synchronized: true) + self._failedAPICallsCollection = Store.main.registerCollection(synchronized: true, limit: 50) } /// If configured for, logs and send to the server a failed API call @@ -447,7 +462,7 @@ public class StoreCenter { if let logs = self._logs { return logs } else { - let logsCollection: StoredCollection = Store.main.registerCollection(synchronized: true) + let logsCollection: StoredCollection = Store.main.registerCollection(synchronized: true, limit: 50) self._logs = logsCollection return logsCollection } diff --git a/LeStorage/StoredCollection.swift b/LeStorage/StoredCollection.swift index e04650c..ac0b30e 100644 --- a/LeStorage/StoredCollection.swift +++ b/LeStorage/StoredCollection.swift @@ -71,7 +71,9 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti /// Indicates if the collection has loaded locally, with or without a file fileprivate(set) public var hasLoaded: Bool = false - init(synchronized: Bool, store: Store, indexed: Bool = false, asynchronousIO: Bool = true, inMemory: Bool = false, sendsUpdate: Bool = true) { + fileprivate(set) var limit: Int? = nil + + init(synchronized: Bool, store: Store, indexed: Bool = false, asynchronousIO: Bool = true, inMemory: Bool = false, sendsUpdate: Bool = true, limit: Int? = nil) { self.synchronized = synchronized self.asynchronousIO = asynchronousIO if indexed { @@ -80,6 +82,7 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti self._inMemory = inMemory self._sendsUpdate = sendsUpdate self._store = store + self.limit = limit self._load() } @@ -222,11 +225,18 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti } else { // insert self.items.append(instance) self._sendInsertionIfNecessary(instance) + self._applyLimitIfPresent() } self._indexes?[instance.id] = instance } + fileprivate func _applyLimitIfPresent() { + if let limit { + self.items = self.items.suffix(limit) + } + } + /// Sends a POST request for the instance, and changes the collection to perform a write public func writeChangeAndInsertOnServer(instance: T) { defer { @@ -308,6 +318,8 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti self._indexes?[instance.id] = instance } + self._applyLimitIfPresent() + } /// Returns the instance corresponding to the provided [id] From b068f3a57b23bc6f381e263dbf5b2576c34273be Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 2 Dec 2024 12:02:25 +0100 Subject: [PATCH 3/6] Fix crash --- LeStorage/StoreCenter.swift | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/LeStorage/StoreCenter.swift b/LeStorage/StoreCenter.swift index 3d351ef..1fba4b6 100644 --- a/LeStorage/StoreCenter.swift +++ b/LeStorage/StoreCenter.swift @@ -470,11 +470,13 @@ public class StoreCenter { /// Logs a message in the logs collection public func log(message: String) { - let log = Log(message: message) - do { - try self._logsCollection().addOrUpdate(instance: log) - } catch { - Logger.error(error) + DispatchQueue.main.async { + let log = Log(message: message) + do { + try self._logsCollection().addOrUpdate(instance: log) + } catch { + Logger.error(error) + } } } From 4c5105f4c3408a5956bf9713d568c82a6ecc8216 Mon Sep 17 00:00:00 2001 From: Laurent Date: Thu, 5 Dec 2024 11:52:21 +0100 Subject: [PATCH 4/6] Stop syncing log collection --- LeStorage/StoreCenter.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LeStorage/StoreCenter.swift b/LeStorage/StoreCenter.swift index 1fba4b6..4fed337 100644 --- a/LeStorage/StoreCenter.swift +++ b/LeStorage/StoreCenter.swift @@ -462,7 +462,7 @@ public class StoreCenter { if let logs = self._logs { return logs } else { - let logsCollection: StoredCollection = Store.main.registerCollection(synchronized: true, limit: 50) + let logsCollection: StoredCollection = Store.main.registerCollection(synchronized: false, limit: 1000) self._logs = logsCollection return logsCollection } From fb9d60ffd287bc7a3ab81465646254ff4c06edbb Mon Sep 17 00:00:00 2001 From: Laurent Date: Thu, 5 Dec 2024 15:37:59 +0100 Subject: [PATCH 5/6] remove logs --- LeStorage/StoredCollection.swift | 3 --- 1 file changed, 3 deletions(-) diff --git a/LeStorage/StoredCollection.swift b/LeStorage/StoredCollection.swift index ac0b30e..c7ff2aa 100644 --- a/LeStorage/StoredCollection.swift +++ b/LeStorage/StoredCollection.swift @@ -433,7 +433,6 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti /// - instance: the object to POST fileprivate func _sendInsertionIfNecessary(_ instance: T) { guard self.synchronized else { - StoreCenter.main.log(message: "cannot send insert: \(T.resourceName()), \(StoreCenter.main.userName() ?? "no user") : sync = \(self.synchronized)") return } Task { @@ -464,7 +463,6 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti /// - instance: the object to PUT fileprivate func _sendUpdateIfNecessary(_ instance: T) { guard self.synchronized, self._sendsUpdate else { - StoreCenter.main.log(message: "cannot send update: \(T.resourceName()), \(StoreCenter.main.userName() ?? "no user") : sync = \(self.synchronized), self._sendsUpdate = \(self._sendsUpdate)") return } Task { @@ -482,7 +480,6 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti /// - instance: the object to DELETE fileprivate func _sendDeletionIfNecessary(_ instance: T) { guard self.synchronized else { - StoreCenter.main.log(message: "cannot send delete: \(T.resourceName()), \(StoreCenter.main.userName() ?? "no user") : sync = \(self.synchronized)") return } Task { From a03ee52c7082ef02abd2d33107d63189bc8c001a Mon Sep 17 00:00:00 2001 From: Laurent Date: Thu, 5 Dec 2024 16:32:05 +0100 Subject: [PATCH 6/6] Fix code for logging reset --- LeStorage/StoreCenter.swift | 7 +++++-- LeStorage/StoredCollection.swift | 6 +++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/LeStorage/StoreCenter.swift b/LeStorage/StoreCenter.swift index 4fed337..96bc011 100644 --- a/LeStorage/StoreCenter.swift +++ b/LeStorage/StoreCenter.swift @@ -252,10 +252,13 @@ public class StoreCenter { } public func resetLoggingCollections() { - self._failedAPICallsCollection?.reset() - self._logs?.reset() + Task { do { + try FileManager.default.removeItem(at: Log.urlForJSONFile()) + try FileManager.default.removeItem(at: FailedAPICall.urlForJSONFile()) + + let facApiCallCollection: ApiCallCollection = try self.apiCallCollection() await facApiCallCollection.reset() let logApiCallCollection: ApiCallCollection = try self.apiCallCollection() diff --git a/LeStorage/StoredCollection.swift b/LeStorage/StoredCollection.swift index c7ff2aa..aefa7a5 100644 --- a/LeStorage/StoredCollection.swift +++ b/LeStorage/StoredCollection.swift @@ -124,7 +124,11 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti if self.asynchronousIO { Task(priority: .high) { - try self._decodeJSONFile() + do { + try self._decodeJSONFile() + } catch { + Logger.error(error) + } } } else { try self._decodeJSONFile()