@@ -78,7 +78,7 @@ pub struct MemStoreSnapshot {
78
78
pub struct MemStoreStateMachine {
79
79
pub last_applied_log : LogId ,
80
80
81
- pub last_membership : Option < MembershipConfig > ,
81
+ pub last_membership : Option < ( LogId , MembershipConfig ) > ,
82
82
83
83
/// A mapping of client IDs to their state info.
84
84
pub client_serial_responses : HashMap < String , ( u64 , Option < String > ) > ,
@@ -302,29 +302,6 @@ impl MemStore {
302
302
std:: cmp:: max ( log_last_id, sm_last_id)
303
303
}
304
304
305
- pub async fn defensive_consistent_log_sm ( & self ) -> Result < ( ) , DefensiveError > {
306
- let log_last_id = {
307
- let log_last = self . log . read ( ) . await ;
308
- log_last. iter ( ) . last ( ) . map ( |( _k, v) | v. log_id ) . unwrap_or_default ( )
309
- } ;
310
-
311
- let sm_last_id = self . sm . read ( ) . await . last_applied_log ;
312
-
313
- if ( log_last_id. index == sm_last_id. index && log_last_id != sm_last_id)
314
- || ( log_last_id. index > sm_last_id. index && log_last_id < sm_last_id)
315
- {
316
- return Err ( DefensiveError :: new (
317
- ErrorSubject :: Log ( log_last_id) ,
318
- Violation :: DirtyLog {
319
- higher_index_log_id : log_last_id,
320
- lower_index_log_id : sm_last_id,
321
- } ,
322
- ) ) ;
323
- }
324
-
325
- Ok ( ( ) )
326
- }
327
-
328
305
pub async fn defensive_apply_index_is_last_applied_plus_one < D : AppData > (
329
306
& self ,
330
307
entries : & [ & Entry < D > ] ,
@@ -512,7 +489,7 @@ impl MemStore {
512
489
pub async fn get_membership_from_log ( & self , upto_index : Option < u64 > ) -> Result < MembershipConfig , StorageError > {
513
490
self . defensive_no_dirty_log ( ) . await ?;
514
491
515
- let membership = {
492
+ let membership_in_log = {
516
493
let log = self . log . read ( ) . await ;
517
494
518
495
let reversed_logs = log. values ( ) . rev ( ) ;
@@ -527,26 +504,19 @@ impl MemStore {
527
504
528
505
// Find membership stored in state machine.
529
506
530
- let ( sm_mem, last_applied) = {
531
- let sm = self . sm . read ( ) . await ;
532
- ( sm. last_membership . clone ( ) , sm. last_applied_log )
533
- } ;
507
+ let ( _, membership_in_sm) = self . last_applied_state ( ) . await ?;
534
508
535
- let membership = match membership {
536
- None => sm_mem,
537
- Some ( ( id, log_mem) ) => {
538
- if id < last_applied {
539
- sm_mem
540
- } else {
541
- Some ( log_mem)
542
- }
543
- }
544
- } ;
509
+ let membership =
510
+ if membership_in_log. as_ref ( ) . map ( |( id, _) | id. index ) > membership_in_sm. as_ref ( ) . map ( |( id, _) | id. index ) {
511
+ membership_in_log
512
+ } else {
513
+ membership_in_sm
514
+ } ;
545
515
546
- // Otherwise, create a default one.
516
+ // Create a default one if both are None .
547
517
548
518
Ok ( match membership {
549
- Some ( cfg) => cfg,
519
+ Some ( ( _id , cfg) ) => cfg,
550
520
None => MembershipConfig :: new_initial ( self . id ) ,
551
521
} )
552
522
}
@@ -573,27 +543,22 @@ impl RaftStorage<ClientRequest, ClientResponse> for MemStore {
573
543
574
544
let membership = self . get_membership_config ( ) . await ?;
575
545
let mut hs = self . hs . write ( ) . await ;
576
- let log = self . log . read ( ) . await ;
577
- let sm = self . sm . read ( ) . await ;
578
546
match & mut * hs {
579
547
Some ( inner) => {
580
548
// Search for two place and use the max one,
581
549
// because when a state machine is installed there could be logs
582
550
// included in the state machine that are not cleaned:
583
551
// - the last log id
584
552
// - the last_applied log id in state machine.
585
- // TODO(xp): add test for RaftStore to ensure it looks for two places.
586
553
587
- let last = log. values ( ) . rev ( ) . next ( ) ;
588
- let last = last. map ( |x| x. log_id ) ;
589
- let last_in_log = last. unwrap_or_default ( ) ;
590
- let last_applied_log = sm. last_applied_log ;
554
+ let last_in_log = self . last_id_in_log ( ) . await ?;
555
+ let ( last_applied, _) = self . last_applied_state ( ) . await ?;
591
556
592
- let last_log_id = max ( last_in_log, last_applied_log ) ;
557
+ let last_log_id = max ( last_in_log, last_applied ) ;
593
558
594
559
Ok ( InitialState {
595
560
last_log_id,
596
- last_applied : last_applied_log ,
561
+ last_applied,
597
562
hard_state : inner. clone ( ) ,
598
563
membership,
599
564
} )
@@ -639,15 +604,15 @@ impl RaftStorage<ClientRequest, ClientResponse> for MemStore {
639
604
Ok ( log. get ( & log_index) . cloned ( ) )
640
605
}
641
606
642
- #[ tracing:: instrument( level = "trace" , skip( self ) ) ]
643
- async fn get_last_log_id ( & self ) -> Result < LogId , StorageError > {
644
- self . defensive_consistent_log_sm ( ) . await ?;
645
-
646
- // TODO: log id must consistent:
647
- let log_last_id = self . log . read ( ) . await . iter ( ) . last ( ) . map ( |( _k, v) | v. log_id ) . unwrap_or_default ( ) ;
648
- let last_applied_id = self . sm . read ( ) . await . last_applied_log ;
607
+ async fn last_id_in_log ( & self ) -> Result < LogId , StorageError > {
608
+ let log = self . log . read ( ) . await ;
609
+ let last = log. iter ( ) . last ( ) . map ( |( _, ent) | ent. log_id ) . unwrap_or_default ( ) ;
610
+ Ok ( last)
611
+ }
649
612
650
- Ok ( max ( log_last_id, last_applied_id) )
613
+ async fn last_applied_state ( & self ) -> Result < ( LogId , Option < ( LogId , MembershipConfig ) > ) , StorageError > {
614
+ let sm = self . sm . read ( ) . await ;
615
+ Ok ( ( sm. last_applied_log , sm. last_membership . clone ( ) ) )
651
616
}
652
617
653
618
#[ tracing:: instrument( level = "trace" , skip( self , range) , fields( range=?range) ) ]
@@ -714,7 +679,7 @@ impl RaftStorage<ClientRequest, ClientResponse> for MemStore {
714
679
res. push ( ClientResponse ( previous) ) ;
715
680
}
716
681
EntryPayload :: ConfigChange ( ref mem) => {
717
- sm. last_membership = Some ( mem. membership . clone ( ) ) ;
682
+ sm. last_membership = Some ( ( entry . log_id , mem. membership . clone ( ) ) ) ;
718
683
res. push ( ClientResponse ( None ) )
719
684
}
720
685
} ;
@@ -734,7 +699,11 @@ impl RaftStorage<ClientRequest, ClientResponse> for MemStore {
734
699
. map_err ( |e| StorageIOError :: new ( ErrorSubject :: StateMachine , ErrorVerb :: Read , e. into ( ) ) ) ?;
735
700
736
701
last_applied_log = sm. last_applied_log ;
737
- membership_config = sm. last_membership . clone ( ) . unwrap_or_else ( || MembershipConfig :: new_initial ( self . id ) ) ;
702
+ membership_config = sm
703
+ . last_membership
704
+ . clone ( )
705
+ . map ( |( _id, mem) | mem)
706
+ . unwrap_or_else ( || MembershipConfig :: new_initial ( self . id ) ) ;
738
707
}
739
708
740
709
let snapshot_size = data. len ( ) ;
0 commit comments