Skip to content

Commit

Permalink
fix(datastore): full sync when sync predicate changes
Browse files Browse the repository at this point in the history
  • Loading branch information
lawmicha committed Feb 8, 2023
1 parent 74de7b9 commit ab127f7
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,15 @@ public struct ModelSyncMetadata: Model {

/// The timestamp (in Unix seconds) at which the last sync was started, as reported by the service
public var lastSync: Int?

/// The sync predicate for this model, extracted out from the sync expression.
public var syncPredicate: String?

public init(id: String,
lastSync: Int?) {
lastSync: Int?,
syncPredicate: String? = nil) {
self.id = id
self.lastSync = lastSync
self.syncPredicate = syncPredicate
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ final class InitialSyncOperation: AsynchronousOperation {
return dataStoreConfiguration.syncPageSize
}

private var lastSyncPredicate: String?

private var currentSyncPredicate: String?

private let initialSyncOperationTopic: PassthroughSubject<InitialSyncOperationEvent, DataStoreError>
var publisher: AnyPublisher<InitialSyncOperationEvent, DataStoreError> {
return initialSyncOperationTopic.eraseToAnyPublisher()
Expand All @@ -50,6 +54,8 @@ final class InitialSyncOperation: AsynchronousOperation {

self.recordsReceived = 0
self.initialSyncOperationTopic = PassthroughSubject<InitialSyncOperationEvent, DataStoreError>()
self.lastSyncPredicate = nil
self.currentSyncPredicate = nil
}

override func main() {
Expand All @@ -74,6 +80,7 @@ final class InitialSyncOperation: AsynchronousOperation {
}

let lastSyncMetadata = getLastSyncMetadata()
self.lastSyncPredicate = lastSyncMetadata?.syncPredicate
guard let lastSync = lastSyncMetadata?.lastSync else {
return nil
}
Expand Down Expand Up @@ -125,7 +132,14 @@ final class InitialSyncOperation: AsynchronousOperation {
$0.modelSchema.name == modelSchema.name
}
let queryPredicate = syncExpression?.modelPredicate()

// TODO: what is the correct way to store the predicate?
self.currentSyncPredicate = String(describing: queryPredicate)

var lastSyncTime = lastSyncTime
// Update `lastSyncTime` to perform a full sync if there is a change in sync predicate
if InitialSyncOperation.isDifferent(lastSyncPredicate, currentSyncPredicate) {
lastSyncTime = nil
}
let completionListener: GraphQLOperation<SyncQueryResult>.ResultListener = { result in
switch result {
case .failure(let apiError):
Expand Down Expand Up @@ -154,6 +168,15 @@ final class InitialSyncOperation: AsynchronousOperation {
api.query(request: nextRequest, listener: wrappedCompletionListener)
}.main()
}

private static func isDifferent(_ lastSyncPredicate: String?, _ currentSyncPredicate: String?) -> Bool {
guard let lastSyncPredicate = lastSyncPredicate,
let currentSyncPredicate = currentSyncPredicate else {
return false
}

return lastSyncPredicate != currentSyncPredicate
}

/// Disposes of the query results: Stops if error, reconciles results if success, and kick off a new query if there
/// is a next token
Expand Down Expand Up @@ -206,7 +229,9 @@ final class InitialSyncOperation: AsynchronousOperation {
return
}

let syncMetadata = ModelSyncMetadata(id: modelSchema.name, lastSync: lastSyncTime)
let syncMetadata = ModelSyncMetadata(id: modelSchema.name,
lastSync: lastSyncTime,
syncPredicate: currentSyncPredicate)
storageAdapter.save(syncMetadata, condition: nil, eagerLoad: true) { result in
switch result {
case .failure(let dataStoreError):
Expand Down

0 comments on commit ab127f7

Please sign in to comment.