@@ -95,24 +95,21 @@ impl SyncClient {
9595 SyncControlRequest :: SyncEvent ( sync_event) => {
9696 let mut active = ActiveEvent :: new ( sync_event) ;
9797
98- let run_result = {
99- let ClientState :: IterationActive ( handle) = & mut self . state else {
100- return Err ( PowerSyncError :: state_error ( "No iteration is active" ) ) ;
101- } ;
102-
103- handle. run ( & mut active)
98+ let ClientState :: IterationActive ( handle) = & mut self . state else {
99+ return Err ( PowerSyncError :: state_error ( "No iteration is active" ) ) ;
104100 } ;
105101
106- match run_result {
102+ match handle . run ( & mut active ) {
107103 Err ( e) => {
108104 self . state = ClientState :: Idle ;
109105 return Err ( e) ;
110106 }
111- Ok ( true ) => {
112- self . state = ClientState :: Idle ;
107+ Ok ( done) => {
108+ if done {
109+ self . state = ClientState :: Idle ;
110+ }
113111 }
114- Ok ( false ) => { }
115- }
112+ } ;
116113
117114 if let Some ( recoverable) = active. recoverable_error . take ( ) {
118115 Err ( recoverable)
@@ -220,18 +217,18 @@ impl SyncIterationHandle {
220217 } ;
221218 let mut context = Context :: from_waker ( & waker) ;
222219
223- let done = if let Poll :: Ready ( result) = self . future . poll ( & mut context) {
224- let close = result?;
220+ Ok (
221+ if let Poll :: Ready ( result) = self . future . poll ( & mut context) {
222+ let close = result?;
225223
226- active
227- . instructions
228- . push ( Instruction :: CloseSyncStream ( close) ) ;
229- true
230- } else {
231- false
232- } ;
233-
234- Ok ( done)
224+ active
225+ . instructions
226+ . push ( Instruction :: CloseSyncStream ( close) ) ;
227+ true
228+ } else {
229+ false
230+ } ,
231+ )
235232 }
236233}
237234
@@ -384,6 +381,13 @@ impl StreamingSyncIteration {
384381 } ) ;
385382 event. instructions . push ( Instruction :: FlushFileSystem { } ) ;
386383
384+ // Persist here so that all database writes happen while preparing the
385+ // transition, keeping apply_transition infallible.
386+ if let Some ( request_id) = target. write_checkpoint {
387+ self . adapter
388+ . persist_last_applied_checkpoint_request_id ( request_id) ?;
389+ }
390+
387391 SyncStateMachineTransition :: SyncLocalChangesApplied {
388392 applied_checkpoint_request_id : target. write_checkpoint ,
389393 partial : None ,
@@ -482,7 +486,7 @@ impl StreamingSyncIteration {
482486 target : & mut SyncTarget ,
483487 event : & mut ActiveEvent ,
484488 transition : SyncStateMachineTransition ,
485- ) -> Result < Option < CloseSyncStream > , PowerSyncError > {
489+ ) -> Option < CloseSyncStream > {
486490 match transition {
487491 SyncStateMachineTransition :: StartTrackingCheckpoint {
488492 progress,
@@ -516,7 +520,7 @@ impl StreamingSyncIteration {
516520 diagnostics. handle_data_line ( line, & * status, & mut event. instructions ) ;
517521 }
518522 }
519- SyncStateMachineTransition :: CloseIteration ( close) => return Ok ( Some ( close) ) ,
523+ SyncStateMachineTransition :: CloseIteration ( close) => return Some ( close) ,
520524 SyncStateMachineTransition :: SyncLocalFailedDueToPendingCrud {
521525 validated_but_not_applied,
522526 } => {
@@ -535,17 +539,13 @@ impl StreamingSyncIteration {
535539 & mut event. instructions ,
536540 ) ;
537541 } else {
538- self . handle_checkpoint_applied (
539- event,
540- timestamp,
541- applied_checkpoint_request_id,
542- ) ?;
542+ self . handle_checkpoint_applied ( event, timestamp, applied_checkpoint_request_id) ;
543543 }
544544 }
545545 SyncStateMachineTransition :: Empty => { }
546546 } ;
547547
548- Ok ( None )
548+ None
549549 }
550550
551551 /// Handles a single sync line.
@@ -559,7 +559,7 @@ impl StreamingSyncIteration {
559559 line : & SyncLineWithSource ,
560560 ) -> Result < Option < CloseSyncStream > , PowerSyncError > {
561561 let transition = self . prepare_handling_sync_line ( target, event, line) ?;
562- self . apply_transition ( target, event, transition)
562+ Ok ( self . apply_transition ( target, event, transition) )
563563 }
564564
565565 /// Runs a full sync iteration, returning nothing when it completes regularly or an error when
@@ -684,7 +684,11 @@ impl StreamingSyncIteration {
684684 line : "Applied pending checkpoint after completed upload" . into ( ) ,
685685 } ) ;
686686
687- self . handle_checkpoint_applied ( event, timestamp, checkpoint. write_checkpoint ) ?;
687+ if let Some ( request_id) = checkpoint. write_checkpoint {
688+ self . adapter
689+ . persist_last_applied_checkpoint_request_id ( request_id) ?;
690+ }
691+ self . handle_checkpoint_applied ( event, timestamp, checkpoint. write_checkpoint ) ;
688692 }
689693 _ => {
690694 event. instructions . push ( Instruction :: LogLine {
@@ -923,11 +927,11 @@ impl StreamingSyncIteration {
923927 /// subscriptions, used to associate [BucketSubscriptionReason::DerivedFromExplicitSubscription].
924928 async fn prepare_request ( & mut self ) -> Result < BeforeCheckpoint , PowerSyncError > {
925929 let event = Self :: receive_event ( ) . await ;
926- if ! matches ! ( & event . event , SyncEvent :: Initialize ) {
930+ let SyncEvent :: Initialize = event . event else {
927931 return Err ( PowerSyncError :: argument_error (
928932 "first event must initialize" ,
929933 ) ) ;
930- }
934+ } ;
931935
932936 let offline_state = self . adapter . offline_sync_state ( ) ?;
933937 self . status . update (
@@ -969,15 +973,18 @@ impl StreamingSyncIteration {
969973 } )
970974 }
971975
976+ /// Emits the instructions and status update for a fully applied checkpoint.
977+ ///
978+ /// The applied checkpoint request id must already have been persisted by the caller: this
979+ /// runs while applying a state transition, which must stay infallible (see
980+ /// [SyncStateMachineTransition]).
972981 fn handle_checkpoint_applied (
973982 & mut self ,
974983 event : & mut ActiveEvent ,
975984 timestamp : TimestampMicros ,
976985 applied_checkpoint_request_id : Option < i64 > ,
977- ) -> Result < ( ) , PowerSyncError > {
986+ ) {
978987 if let Some ( request_id) = applied_checkpoint_request_id {
979- self . adapter
980- . persist_last_applied_checkpoint_request_id ( request_id) ?;
981988 event
982989 . instructions
983990 . push ( Instruction :: CheckpointRequestApplied { request_id } ) ;
@@ -989,8 +996,6 @@ impl StreamingSyncIteration {
989996 |status| status. applied_checkpoint ( timestamp) ,
990997 & mut event. instructions ,
991998 ) ;
992-
993- Ok ( ( ) )
994999 }
9951000}
9961001
0 commit comments