sync2
Laurent 1 year ago
parent aa78348e98
commit 214420f98a
  1. 16
      LeStorage/ApiCallCollection.swift
  2. 5
      LeStorage/StoredCollection.swift

@ -19,6 +19,10 @@ protocol SomeCallCollection {
} }
enum ApiCallError: Error {
case cantCreateCall
}
/// ApiCallCollection is an object communicating with a server to synchronize data managed locally /// ApiCallCollection is an object communicating with a server to synchronize data managed locally
/// The Api calls are serialized and stored in a JSON file /// The Api calls are serialized and stored in a JSON file
/// Failing Api calls are stored forever and will be executed again later /// Failing Api calls are stored forever and will be executed again later
@ -227,12 +231,17 @@ actor ApiCallCollection<T: Storable>: SomeCallCollection {
/// Creates an API call for the Storable [instance] and an HTTP [method] /// Creates an API call for the Storable [instance] and an HTTP [method]
fileprivate func _createCall(_ instance: T, method: HTTPMethod) throws -> ApiCall<T> { fileprivate func _createCall(_ instance: T, method: HTTPMethod) throws -> ApiCall<T> {
do {
let jsonString = try instance.jsonString() let jsonString = try instance.jsonString()
return ApiCall(method: method, dataId: instance.stringId, body: jsonString) return ApiCall(method: method, dataId: instance.stringId, body: jsonString)
} catch {
StoreCenter.main.log(message: "call could not be created for \(T.resourceName()): \(error.localizedDescription)")
throw ApiCallError.cantCreateCall
}
} }
/// Prepares a call for execution by updating its properties and adding it to its collection for storage /// Prepares a call for execution by updating its properties and adding it to its collection for storage
fileprivate func _prepareCall(apiCall: ApiCall<T>) throws { fileprivate func _prepareCall(apiCall: ApiCall<T>) {
apiCall.lastAttemptDate = Date() apiCall.lastAttemptDate = Date()
apiCall.attemptsCount += 1 apiCall.attemptsCount += 1
self.addOrUpdate(apiCall) self.addOrUpdate(apiCall)
@ -244,6 +253,7 @@ actor ApiCallCollection<T: Storable>: SomeCallCollection {
return try await self._synchronize(instance, method: HTTPMethod.post) return try await self._synchronize(instance, method: HTTPMethod.post)
} catch { } catch {
self.rescheduleApiCallsIfNecessary() self.rescheduleApiCallsIfNecessary()
StoreCenter.main.log(message: "POST failed for \(instance)")
Logger.error(error) Logger.error(error)
} }
return nil return nil
@ -256,6 +266,7 @@ actor ApiCallCollection<T: Storable>: SomeCallCollection {
return try await self._synchronize(instance, method: HTTPMethod.put) return try await self._synchronize(instance, method: HTTPMethod.put)
} catch { } catch {
self.rescheduleApiCallsIfNecessary() self.rescheduleApiCallsIfNecessary()
StoreCenter.main.log(message: "PUT failed for \(instance)")
Logger.error(error) Logger.error(error)
} }
return nil return nil
@ -267,6 +278,7 @@ actor ApiCallCollection<T: Storable>: SomeCallCollection {
let _: Empty? = try await self._synchronize(instance, method: HTTPMethod.delete) let _: Empty? = try await self._synchronize(instance, method: HTTPMethod.delete)
} catch { } catch {
self.rescheduleApiCallsIfNecessary() self.rescheduleApiCallsIfNecessary()
StoreCenter.main.log(message: "DELETE failed for \(instance)")
Logger.error(error) Logger.error(error)
} }
return return
@ -275,7 +287,7 @@ actor ApiCallCollection<T: Storable>: SomeCallCollection {
/// Initiates the process of sending the data with the server /// Initiates the process of sending the data with the server
fileprivate func _synchronize<V: Decodable>(_ instance: T, method: HTTPMethod) async throws -> V? { fileprivate func _synchronize<V: Decodable>(_ instance: T, method: HTTPMethod) async throws -> V? {
if let apiCall = try self._callForInstance(instance, method: method) { if let apiCall = try self._callForInstance(instance, method: method) {
try self._prepareCall(apiCall: apiCall) self._prepareCall(apiCall: apiCall)
return try await self._executeApiCall(apiCall) return try await self._executeApiCall(apiCall)
} else { } else {
return nil return nil

@ -399,14 +399,13 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti
/// Writes all the items as a json array inside a file /// Writes all the items as a json array inside a file
fileprivate func _write() { fileprivate func _write() {
// Logger.log("Start write to \(T.fileName())...")
do { do {
let jsonString: String = try self.items.jsonString() let jsonString: String = try self.items.jsonString()
try self._store.write(content: jsonString, fileName: T.fileName()) try self._store.write(content: jsonString, fileName: T.fileName())
} catch { } catch {
Logger.error(error) // TODO how to notify the main project Logger.error(error)
StoreCenter.main.log(message: "write failed for \(T.resourceName()): \(error.localizedDescription)")
} }
// Logger.log("End write")
} }
/// Simply clears the items of the collection /// Simply clears the items of the collection

Loading…
Cancel
Save