@@ -20,7 +20,14 @@ final class InitialSyncOperation: AsynchronousOperation {
20
20
private let modelType : Model . Type
21
21
private let completion : AWSInitialSyncOrchestrator . SyncOperationResultHandler
22
22
23
- private var lastSyncTime : Int ?
23
+ private var recordsReceived : UInt
24
+
25
+ private var syncMaxRecords : UInt {
26
+ return dataStoreConfiguration. syncMaxRecords
27
+ }
28
+ private var syncPageSize : UInt {
29
+ return dataStoreConfiguration. syncPageSize
30
+ }
24
31
25
32
init ( modelType: Model . Type ,
26
33
api: APICategoryGraphQLBehavior ? ,
@@ -34,6 +41,7 @@ final class InitialSyncOperation: AsynchronousOperation {
34
41
self . storageAdapter = storageAdapter
35
42
self . dataStoreConfiguration = dataStoreConfiguration
36
43
self . completion = completion
44
+ self . recordsReceived = 0
37
45
}
38
46
39
47
override func main( ) {
@@ -43,19 +51,19 @@ final class InitialSyncOperation: AsynchronousOperation {
43
51
}
44
52
45
53
log. info ( " Beginning sync for \( modelType. modelName) " )
46
- setUpLastSyncTime ( )
47
- query ( )
54
+ let lastSyncTime = getLastSyncTime ( )
55
+ query ( lastSyncTime : lastSyncTime )
48
56
}
49
57
50
- private func setUpLastSyncTime ( ) {
58
+ private func getLastSyncTime ( ) -> Int ? {
51
59
guard !isCancelled else {
52
60
super. finish ( )
53
- return
61
+ return nil
54
62
}
55
63
56
64
let lastSyncMetadata = getLastSyncMetadata ( )
57
65
guard let lastSync = lastSyncMetadata? . lastSync else {
58
- return
66
+ return nil
59
67
}
60
68
61
69
//TODO: Update to use TimeInterval.milliseconds when it is pushed to master branch
@@ -64,14 +72,11 @@ final class InitialSyncOperation: AsynchronousOperation {
64
72
let secondsSinceLastSync = ( lastSyncDate. timeIntervalSinceNow * - 1 )
65
73
if secondsSinceLastSync < 0 {
66
74
log. info ( " lastSyncTime was in the future, assuming base query " )
67
- lastSyncTime = nil
68
- return
75
+ return nil
69
76
}
70
77
71
78
let shouldDoDeltaQuery = secondsSinceLastSync < dataStoreConfiguration. syncInterval
72
- if shouldDoDeltaQuery {
73
- lastSyncTime = lastSync
74
- }
79
+ return shouldDoDeltaQuery ? lastSync : nil
75
80
}
76
81
77
82
private func getLastSyncMetadata( ) -> ModelSyncMetadata ? {
@@ -95,7 +100,7 @@ final class InitialSyncOperation: AsynchronousOperation {
95
100
96
101
}
97
102
98
- private func query( nextToken: String ? = nil ) {
103
+ private func query( lastSyncTime : Int ? , nextToken: String ? = nil ) {
99
104
guard !isCancelled else {
100
105
super. finish ( )
101
106
return
@@ -105,8 +110,10 @@ final class InitialSyncOperation: AsynchronousOperation {
105
110
finish ( result: . failure( DataStoreError . nilAPIHandle ( ) ) )
106
111
return
107
112
}
108
-
113
+ let minSyncPageSize = Int ( min ( syncMaxRecords - recordsReceived, syncPageSize) )
114
+ let limit = minSyncPageSize < 0 ? Int ( syncPageSize) : minSyncPageSize
109
115
let request = GraphQLRequest< SyncQueryResult> . syncQuery( modelType: modelType,
116
+ limit: limit,
110
117
nextToken: nextToken,
111
118
lastSync: lastSyncTime)
112
119
@@ -116,7 +123,7 @@ final class InitialSyncOperation: AsynchronousOperation {
116
123
// TODO: Retry query on error
117
124
self . finish ( result: . failure( DataStoreError . api ( apiError) ) )
118
125
case . completed( let graphQLResult) :
119
- self . handleQueryResults ( graphQLResult: graphQLResult)
126
+ self . handleQueryResults ( lastSyncTime : lastSyncTime , graphQLResult: graphQLResult)
120
127
default :
121
128
break
122
129
}
@@ -125,7 +132,7 @@ final class InitialSyncOperation: AsynchronousOperation {
125
132
126
133
/// Disposes of the query results: Stops if error, reconciles results if success, and kick off a new query if there
127
134
/// is a next token
128
- private func handleQueryResults( graphQLResult: Result < SyncQueryResult , GraphQLResponseError < SyncQueryResult > > ) {
135
+ private func handleQueryResults( lastSyncTime : Int ? , graphQLResult: Result < SyncQueryResult , GraphQLResponseError < SyncQueryResult > > ) {
129
136
guard !isCancelled else {
130
137
super. finish ( )
131
138
return
@@ -146,23 +153,23 @@ final class InitialSyncOperation: AsynchronousOperation {
146
153
}
147
154
148
155
let items = syncQueryResult. items
149
- lastSyncTime = syncQueryResult . startedAt
156
+ recordsReceived += UInt ( items . count )
150
157
151
158
for item in items {
152
159
reconciliationQueue. offer ( item)
153
160
}
154
161
155
- if let nextToken = syncQueryResult. nextToken {
162
+ if let nextToken = syncQueryResult. nextToken, recordsReceived < syncMaxRecords {
156
163
DispatchQueue . global ( ) . async {
157
- self . query ( nextToken: nextToken)
164
+ self . query ( lastSyncTime : lastSyncTime , nextToken: nextToken)
158
165
}
159
166
} else {
160
- updateModelSyncMetadata ( )
167
+ updateModelSyncMetadata ( lastSyncTime : syncQueryResult . startedAt )
161
168
}
162
169
163
170
}
164
171
165
- private func updateModelSyncMetadata( ) {
172
+ private func updateModelSyncMetadata( lastSyncTime : Int ? ) {
166
173
guard !isCancelled else {
167
174
super. finish ( )
168
175
return
0 commit comments