@@ -208,11 +208,13 @@ impl StreamingSyncIteration {
208
208
}
209
209
210
210
async fn run ( mut self ) -> Result < ( ) , SQLiteError > {
211
- let mut validated = None :: < OwnedCheckpoint > ;
212
- let mut applied = None :: < OwnedCheckpoint > ;
213
-
214
211
let mut target = SyncTarget :: BeforeCheckpoint ( self . prepare_request ( ) . await ?) ;
215
212
213
+ // A checkpoint that has been fully received and validated, but couldn't be applied due to
214
+ // pending local data. We will retry applying this checkpoint when the client SDK informs us
215
+ // that it has finished uploading changes.
216
+ let mut validated_but_not_applied = None :: < OwnedCheckpoint > ;
217
+
216
218
loop {
217
219
let event = Self :: receive_event ( ) . await ;
218
220
@@ -223,14 +225,44 @@ impl StreamingSyncIteration {
223
225
SyncEvent :: TearDown => break ,
224
226
SyncEvent :: TextLine { data } => serde_json:: from_str ( data) ?,
225
227
SyncEvent :: BinaryLine { data } => bson:: from_bytes ( data) ?,
228
+ SyncEvent :: UploadFinished => {
229
+ if let Some ( checkpoint) = validated_but_not_applied. take ( ) {
230
+ let result = self . adapter . sync_local ( & checkpoint, None ) ?;
231
+
232
+ match result {
233
+ SyncLocalResult :: ChangesApplied => {
234
+ event. instructions . push ( Instruction :: LogLine {
235
+ severity : LogSeverity :: DEBUG ,
236
+ line : "Applied pending checkpoint after completed upload"
237
+ . into ( ) ,
238
+ } ) ;
239
+
240
+ self . handle_checkpoint_applied ( & checkpoint, event) ?;
241
+ }
242
+ _ => {
243
+ event. instructions . push ( Instruction :: LogLine {
244
+ severity : LogSeverity :: WARNING ,
245
+ line : "Could not apply pending checkpoint even after completed upload"
246
+ . into ( ) ,
247
+ } ) ;
248
+ }
249
+ }
250
+ }
251
+
252
+ continue ;
253
+ }
226
254
SyncEvent :: DidRefreshToken => {
227
255
// Break so that the client SDK starts another iteration.
228
256
break ;
229
257
}
230
258
} ;
231
259
260
+ self . status
261
+ . update ( |s| s. mark_connected ( ) , & mut event. instructions ) ;
262
+
232
263
match line {
233
264
SyncLine :: Checkpoint ( checkpoint) => {
265
+ validated_but_not_applied = None ;
234
266
let to_delete = target. track_checkpoint ( & checkpoint) ;
235
267
236
268
self . adapter
@@ -252,6 +284,7 @@ impl StreamingSyncIteration {
252
284
} ;
253
285
254
286
target. apply_diff ( & diff) ;
287
+ validated_but_not_applied = None ;
255
288
self . adapter
256
289
. delete_buckets ( diff. removed_buckets . iter ( ) . copied ( ) ) ?;
257
290
@@ -280,29 +313,25 @@ impl StreamingSyncIteration {
280
313
// await new Promise((resolve) => setTimeout(resolve, 50));
281
314
event. instructions . push ( Instruction :: LogLine {
282
315
severity : LogSeverity :: WARNING ,
283
- line : format ! ( "Could not apply checkpoint, {checkpoint_result}" ) ,
316
+ line : format ! ( "Could not apply checkpoint, {checkpoint_result}" )
317
+ . into ( ) ,
284
318
} ) ;
285
319
break ;
286
320
}
287
321
SyncLocalResult :: PendingLocalChanges => {
288
322
event. instructions . push ( Instruction :: LogLine {
289
- severity : LogSeverity :: WARNING ,
290
- line : format ! ( "TODO: Await pending uploads and try again" ) ,
291
- } ) ;
292
- break ;
323
+ severity : LogSeverity :: INFO ,
324
+ line : "Could not apply checkpoint due to local data. Will retry at completed upload or next checkpoint." . into ( ) ,
325
+ } ) ;
326
+
327
+ validated_but_not_applied = Some ( target. clone ( ) ) ;
293
328
}
294
329
SyncLocalResult :: ChangesApplied => {
295
330
event. instructions . push ( Instruction :: LogLine {
296
331
severity : LogSeverity :: DEBUG ,
297
- line : format ! ( "Validated and applied checkpoint" ) ,
332
+ line : "Validated and applied checkpoint" . into ( ) ,
298
333
} ) ;
299
- event. instructions . push ( Instruction :: DidCompleteSync { } ) ;
300
-
301
- let now = self . adapter . now ( ) ?;
302
- self . status . update (
303
- |status| status. applied_checkpoint ( target, now) ,
304
- & mut event. instructions ,
305
- ) ;
334
+ self . handle_checkpoint_applied ( target, event) ?;
306
335
}
307
336
}
308
337
}
@@ -328,7 +357,8 @@ impl StreamingSyncIteration {
328
357
severity : LogSeverity :: WARNING ,
329
358
line : format ! (
330
359
"Could not apply partial checkpoint, {checkpoint_result}"
331
- ) ,
360
+ )
361
+ . into ( ) ,
332
362
} ) ;
333
363
break ;
334
364
}
@@ -407,6 +437,22 @@ impl StreamingSyncIteration {
407
437
. push ( Instruction :: EstablishSyncStream { request } ) ;
408
438
Ok ( local_bucket_names)
409
439
}
440
+
441
+ fn handle_checkpoint_applied (
442
+ & mut self ,
443
+ target : & OwnedCheckpoint ,
444
+ event : & mut ActiveEvent ,
445
+ ) -> Result < ( ) , ResultCode > {
446
+ event. instructions . push ( Instruction :: DidCompleteSync { } ) ;
447
+
448
+ let now = self . adapter . now ( ) ?;
449
+ self . status . update (
450
+ |status| status. applied_checkpoint ( target, now) ,
451
+ & mut event. instructions ,
452
+ ) ;
453
+
454
+ Ok ( ( ) )
455
+ }
410
456
}
411
457
412
458
#[ derive( Debug ) ]
@@ -451,7 +497,7 @@ impl SyncTarget {
451
497
}
452
498
}
453
499
454
- #[ derive( Debug ) ]
500
+ #[ derive( Debug , Clone ) ]
455
501
pub struct OwnedCheckpoint {
456
502
pub last_op_id : i64 ,
457
503
pub write_checkpoint : Option < i64 > ,
@@ -485,7 +531,7 @@ impl OwnedCheckpoint {
485
531
}
486
532
}
487
533
488
- #[ derive( Debug ) ]
534
+ #[ derive( Debug , Clone ) ]
489
535
pub struct OwnedBucketChecksum {
490
536
pub bucket : String ,
491
537
pub checksum : i32 ,
0 commit comments