Skip to content

Commit b02c3b7

Browse files
authored
feat: Using config to decide base query or delta query (#386)
1 parent 3986cf5 commit b02c3b7

File tree

2 files changed

+80
-15
lines changed

2 files changed

+80
-15
lines changed

AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/InitialSync/InitialSyncOperation.swift

+18-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,24 @@ final class InitialSyncOperation: AsynchronousOperation {
5454
}
5555

5656
let lastSyncMetadata = getLastSyncMetadata()
57-
lastSyncTime = lastSyncMetadata?.lastSync
57+
guard let lastSync = lastSyncMetadata?.lastSync else {
58+
return
59+
}
60+
61+
//TODO: Update to use TimeInterval.milliseconds when it is pushed to master branch
62+
// https://github.com/aws-amplify/amplify-ios/issues/398
63+
let lastSyncDate = Date(timeIntervalSince1970: TimeInterval(lastSync) / 1_000)
64+
let secondsSinceLastSync = (lastSyncDate.timeIntervalSinceNow * -1)
65+
if secondsSinceLastSync < 0 {
66+
log.info("lastSyncTime was in the future, assuming base query")
67+
lastSyncTime = nil
68+
return
69+
}
70+
71+
let shouldDoDeltaQuery = secondsSinceLastSync < dataStoreConfiguration.syncInterval
72+
if shouldDoDeltaQuery {
73+
lastSyncTime = lastSync
74+
}
5875
}
5976

6077
private func getLastSyncMetadata() -> ModelSyncMetadata? {

AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Sync/InitialSync/InitialSyncOperationTests.swift

+62-14
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ class InitialSyncOperationTests: XCTestCase {
2626
/// - It reads sync metadata from storage
2727
func testReadsMetadata() {
2828
let responder = QueryRequestListenerResponder<PaginatedList<AnyModel>> { _, listener in
29-
let startedAt = Int(Date().timeIntervalSince1970)
30-
let list = PaginatedList<AnyModel>(items: [], nextToken: nil, startedAt: startedAt)
29+
let startDateMilliseconds = Int(Date().timeIntervalSince1970) * 1_000
30+
let list = PaginatedList<AnyModel>(items: [], nextToken: nil, startedAt: startDateMilliseconds)
3131
let event: GraphQLOperation<PaginatedList<AnyModel>>.Event = .completed(.success(list))
3232
listener?(event)
3333
return nil
@@ -63,8 +63,8 @@ class InitialSyncOperationTests: XCTestCase {
6363
func testQueriesAPI() {
6464
let apiWasQueried = expectation(description: "API was queried for a PaginatedList of AnyModel")
6565
let responder = QueryRequestListenerResponder<PaginatedList<AnyModel>> { _, listener in
66-
let startedAt = Int(Date().timeIntervalSince1970)
67-
let list = PaginatedList<AnyModel>(items: [], nextToken: nil, startedAt: startedAt)
66+
let startDateMilliseconds = Int(Date().timeIntervalSince1970) * 1_000
67+
let list = PaginatedList<AnyModel>(items: [], nextToken: nil, startedAt: startDateMilliseconds)
6868
let event: GraphQLOperation<PaginatedList<AnyModel>>.Event = .completed(.success(list))
6969
listener?(event)
7070
apiWasQueried.fulfill()
@@ -97,8 +97,8 @@ class InitialSyncOperationTests: XCTestCase {
9797
/// - The method invokes a completion callback when complete
9898
func testInvokesCompletionCallback() {
9999
let responder = QueryRequestListenerResponder<PaginatedList<AnyModel>> { _, listener in
100-
let startedAt = Int(Date().timeIntervalSince1970)
101-
let list = PaginatedList<AnyModel>(items: [], nextToken: nil, startedAt: startedAt)
100+
let startDateMilliseconds = Int(Date().timeIntervalSince1970) * 1_000
101+
let list = PaginatedList<AnyModel>(items: [], nextToken: nil, startedAt: startDateMilliseconds)
102102
let event: GraphQLOperation<PaginatedList<AnyModel>>.Event = .completed(.success(list))
103103
listener?(event)
104104
return nil
@@ -173,15 +173,15 @@ class InitialSyncOperationTests: XCTestCase {
173173
/// - The method submits the returned data to the reconciliation queue
174174
func testSubmitsToReconciliationQueue() {
175175
let responder = QueryRequestListenerResponder<PaginatedList<AnyModel>> { _, listener in
176-
let startedAt = Int(Date().timeIntervalSince1970)
176+
let startedAtMilliseconds = Int(Date().timeIntervalSince1970) * 1_000
177177
let model = MockSynced(id: "1")
178178
let anyModel = AnyModel(model)
179179
let metadata = MutationSyncMetadata(id: "1",
180180
deleted: false,
181181
lastChangedAt: Int(Date().timeIntervalSince1970),
182182
version: 1)
183183
let mutationSync = MutationSync(model: anyModel, syncMetadata: metadata)
184-
let list = PaginatedList<AnyModel>(items: [mutationSync], nextToken: nil, startedAt: startedAt)
184+
let list = PaginatedList<AnyModel>(items: [mutationSync], nextToken: nil, startedAt: startedAtMilliseconds)
185185
let event: GraphQLOperation<PaginatedList<AnyModel>>.Event = .completed(.success(list))
186186
listener?(event)
187187
return nil
@@ -221,9 +221,9 @@ class InitialSyncOperationTests: XCTestCase {
221221
/// - Then:
222222
/// - The method submits the returned data to the reconciliation queue
223223
func testUpdatesSyncMetadata() throws {
224-
let startDateSeconds = Int(Date().timeIntervalSince1970)
224+
let startDateMilliseconds = Int(Date().timeIntervalSince1970) * 1_000
225225
let responder = QueryRequestListenerResponder<PaginatedList<AnyModel>> { _, listener in
226-
let startedAt = startDateSeconds
226+
let startedAt = startDateMilliseconds
227227
let list = PaginatedList<AnyModel>(items: [], nextToken: nil, startedAt: startedAt)
228228
let event: GraphQLOperation<PaginatedList<AnyModel>>.Event = .completed(.success(list))
229229
listener?(event)
@@ -256,7 +256,7 @@ class InitialSyncOperationTests: XCTestCase {
256256
return
257257
}
258258

259-
XCTAssertEqual(syncMetadata.lastSync, startDateSeconds)
259+
XCTAssertEqual(syncMetadata.lastSync, startDateMilliseconds)
260260
}
261261

262262
/// - Given: An InitialSyncOperation in a system with previous sync metadata
@@ -266,12 +266,12 @@ class InitialSyncOperationTests: XCTestCase {
266266
/// - It performs a sync query against the API category with a "lastSync" time from the last start time of
267267
/// the stored metadata
268268
func testQueriesFromLastSync() throws {
269-
let startDateSeconds = Int(Date().timeIntervalSince1970) - 100
269+
let startDateMilliseconds = (Int(Date().timeIntervalSince1970) - 100) * 1_000
270270

271271
let storageAdapter = try SQLiteStorageEngineAdapter(connection: Connection(.inMemory))
272272
try storageAdapter.setUp(models: StorageEngine.systemModels + [MockSynced.self])
273273

274-
let syncMetadata = ModelSyncMetadata(id: MockSynced.modelName, lastSync: startDateSeconds)
274+
let syncMetadata = ModelSyncMetadata(id: MockSynced.modelName, lastSync: startDateMilliseconds)
275275
let syncMetadataSaved = expectation(description: "Sync metadata saved")
276276
storageAdapter.save(syncMetadata) { result in
277277
switch result {
@@ -286,7 +286,7 @@ class InitialSyncOperationTests: XCTestCase {
286286
let apiWasQueried = expectation(description: "API was queried for a PaginatedList of AnyModel")
287287
let responder = QueryRequestListenerResponder<PaginatedList<AnyModel>> { request, listener in
288288
let lastSync = request.variables?["lastSync"] as? Int
289-
XCTAssertEqual(lastSync, startDateSeconds)
289+
XCTAssertEqual(lastSync, startDateMilliseconds)
290290

291291
let list = PaginatedList<AnyModel>(items: [], nextToken: nil, startedAt: nil)
292292
let event: GraphQLOperation<PaginatedList<AnyModel>>.Event = .completed(.success(list))
@@ -310,4 +310,52 @@ class InitialSyncOperationTests: XCTestCase {
310310

311311
wait(for: [apiWasQueried], timeout: 1.0)
312312
}
313+
314+
func testBaseQueryWhenExpiredLastSync() throws {
315+
//Set start date to 100 seconds in the past
316+
let startDateMilliSeconds = (Int(Date().timeIntervalSince1970) - 100) * 1_000
317+
318+
let storageAdapter = try SQLiteStorageEngineAdapter(connection: Connection(.inMemory))
319+
try storageAdapter.setUp(models: StorageEngine.systemModels + [MockSynced.self])
320+
321+
let syncMetadata = ModelSyncMetadata(id: MockSynced.modelName, lastSync: startDateMilliSeconds)
322+
let syncMetadataSaved = expectation(description: "Sync metadata saved")
323+
storageAdapter.save(syncMetadata) { result in
324+
switch result {
325+
case .failure(let dataStoreError):
326+
XCTAssertNil(dataStoreError)
327+
case .success:
328+
syncMetadataSaved.fulfill()
329+
}
330+
}
331+
wait(for: [syncMetadataSaved], timeout: 1.0)
332+
333+
let apiWasQueried = expectation(description: "API was queried for a PaginatedList of AnyModel")
334+
let responder = QueryRequestListenerResponder<PaginatedList<AnyModel>> { request, listener in
335+
let lastSync = request.variables?["lastSync"] as? Int
336+
XCTAssertNil(lastSync)
337+
338+
let list = PaginatedList<AnyModel>(items: [], nextToken: nil, startedAt: nil)
339+
let event: GraphQLOperation<PaginatedList<AnyModel>>.Event = .completed(.success(list))
340+
listener?(event)
341+
apiWasQueried.fulfill()
342+
return nil
343+
}
344+
345+
let apiPlugin = MockAPICategoryPlugin()
346+
apiPlugin.responders[.queryRequestListener] = responder
347+
348+
let reconciliationQueue = MockReconciliationQueue()
349+
let configuration = DataStoreConfiguration.custom(syncInterval: 60)
350+
let operation = InitialSyncOperation(
351+
modelType: MockSynced.self,
352+
api: apiPlugin,
353+
reconciliationQueue: reconciliationQueue,
354+
storageAdapter: storageAdapter,
355+
dataStoreConfiguration: configuration) {_ in }
356+
357+
operation.main()
358+
359+
wait(for: [apiWasQueried], timeout: 1.0)
360+
}
313361
}

0 commit comments

Comments
 (0)