@@ -397,8 +397,16 @@ impl Database {
397
397
let start_frame_no = sync_ctx. durable_frame_num + 1 ;
398
398
let end_frame_no = max_frame_no;
399
399
400
- for frame_no in start_frame_no..end_frame_no+1 {
401
- self . push_one_frame ( & conn, & sync_ctx, generation, frame_no, page_size) . await ?;
400
+ let mut frame_no = start_frame_no;
401
+ while frame_no <= end_frame_no {
402
+ // The server returns its maximum frame number. To avoid resending
403
+ // frames the server already knows about, we need to update the
404
+ // frame number to the one returned by the server.
405
+ let max_frame_no = self . push_one_frame ( & conn, & sync_ctx, generation, frame_no, page_size) . await ?;
406
+ if max_frame_no > frame_no {
407
+ frame_no = max_frame_no;
408
+ }
409
+ frame_no += 1 ;
402
410
}
403
411
404
412
let frame_count = end_frame_no - start_frame_no + 1 ;
@@ -409,7 +417,7 @@ impl Database {
409
417
}
410
418
411
419
#[ cfg( feature = "sync" ) ]
412
- async fn push_one_frame ( & self , conn : & Connection , sync_ctx : & SyncContext , generation : u32 , frame_no : u32 , page_size : u32 ) -> Result < ( ) > {
420
+ async fn push_one_frame ( & self , conn : & Connection , sync_ctx : & SyncContext , generation : u32 , frame_no : u32 , page_size : u32 ) -> Result < u32 > {
413
421
let frame_size: usize = 24 +page_size as usize ;
414
422
let frame = vec ! [ 0 ; frame_size] ;
415
423
let rc = unsafe {
@@ -419,12 +427,12 @@ impl Database {
419
427
return Err ( crate :: errors:: Error :: SqliteFailure ( rc as std:: ffi:: c_int , format ! ( "Failed to get frame: {}" , frame_no) ) ) ;
420
428
}
421
429
let uri = format ! ( "{}/sync/{}/{}/{}" , sync_ctx. sync_url, generation, frame_no, frame_no+1 ) ;
422
- self . push_with_retry ( uri, & sync_ctx. auth_token , frame. to_vec ( ) , sync_ctx. max_retries ) . await ?;
423
- Ok ( ( ) )
430
+ let max_frame_no = self . push_with_retry ( uri, & sync_ctx. auth_token , frame. to_vec ( ) , sync_ctx. max_retries ) . await ?;
431
+ Ok ( max_frame_no )
424
432
}
425
433
426
434
#[ cfg( feature = "sync" ) ]
427
- async fn push_with_retry ( & self , uri : String , auth_token : & Option < String > , frame : Vec < u8 > , max_retries : usize ) -> Result < ( ) > {
435
+ async fn push_with_retry ( & self , uri : String , auth_token : & Option < String > , frame : Vec < u8 > , max_retries : usize ) -> Result < u32 > {
428
436
let mut nr_retries = 0 ;
429
437
loop {
430
438
let client = reqwest:: Client :: new ( ) ;
@@ -437,7 +445,9 @@ impl Database {
437
445
}
438
446
let res = builder. body ( frame. to_vec ( ) ) . send ( ) . await . unwrap ( ) ;
439
447
if res. status ( ) . is_success ( ) {
440
- return Ok ( ( ) ) ;
448
+ let resp = res. json :: < serde_json:: Value > ( ) . await . unwrap ( ) ;
449
+ let max_frame_no = resp. get ( "max_frame_no" ) . unwrap ( ) . as_u64 ( ) . unwrap ( ) ;
450
+ return Ok ( max_frame_no as u32 ) ;
441
451
}
442
452
if nr_retries > max_retries {
443
453
return Err ( crate :: errors:: Error :: ConnectionFailed ( format ! ( "Failed to push frame: {}" , res. status( ) ) ) ) ;
0 commit comments