@@ -74,6 +74,9 @@ pub struct MemStoreSnapshot {
74
74
#[ derive( Serialize , Deserialize , Debug , Default , Clone ) ]
75
75
pub struct MemStoreStateMachine {
76
76
pub last_applied_log : LogId ,
77
+
78
+ pub last_membership : Option < MembershipConfig > ,
79
+
77
80
/// A mapping of client IDs to their state info.
78
81
pub client_serial_responses : HashMap < String , ( u64 , Option < String > ) > ,
79
82
/// The current status of a client by ID.
@@ -233,7 +236,7 @@ impl RaftStorage<ClientRequest, ClientResponse> for MemStore {
233
236
async fn get_log_entries ( & self , start : u64 , stop : u64 ) -> Result < Vec < Entry < ClientRequest > > > {
234
237
// Invalid request, return empty vec.
235
238
if start > stop {
236
- tracing:: error!( "invalid request, start > stop" ) ;
239
+ tracing:: error!( "get_log_entries: invalid request, start({}) > stop({})" , start , stop ) ;
237
240
return Ok ( vec ! [ ] ) ;
238
241
}
239
242
let log = self . log . read ( ) . await ;
@@ -243,7 +246,7 @@ impl RaftStorage<ClientRequest, ClientResponse> for MemStore {
243
246
#[ tracing:: instrument( level = "trace" , skip( self ) ) ]
244
247
async fn delete_logs_from ( & self , start : u64 , stop : Option < u64 > ) -> Result < ( ) > {
245
248
if stop. as_ref ( ) . map ( |stop| & start > stop) . unwrap_or ( false ) {
246
- tracing:: error!( "invalid request, start > stop" ) ;
249
+ tracing:: error!( "delete_logs_from: invalid request, start({}) > stop({:?})" , start , stop ) ;
247
250
return Ok ( ( ) ) ;
248
251
}
249
252
let mut log = self . log . write ( ) . await ;
@@ -276,50 +279,73 @@ impl RaftStorage<ClientRequest, ClientResponse> for MemStore {
276
279
Ok ( ( ) )
277
280
}
278
281
279
- #[ tracing:: instrument( level = "trace" , skip( self , data ) ) ]
280
- async fn apply_entry_to_state_machine ( & self , index : & LogId , data : & ClientRequest ) -> Result < ClientResponse > {
282
+ #[ tracing:: instrument( level = "trace" , skip( self , entry ) ) ]
283
+ async fn apply_entry_to_state_machine ( & self , entry : & Entry < ClientRequest > ) -> Result < ClientResponse > {
281
284
let mut sm = self . sm . write ( ) . await ;
282
- sm. last_applied_log = * index;
283
- if let Some ( ( serial, res) ) = sm. client_serial_responses . get ( & data. client ) {
284
- if serial == & data. serial {
285
- return Ok ( ClientResponse ( res. clone ( ) ) ) ;
285
+ sm. last_applied_log = entry. log_id ;
286
+
287
+ return match entry. payload {
288
+ EntryPayload :: Blank => return Ok ( ClientResponse ( None ) ) ,
289
+ EntryPayload :: SnapshotPointer ( _) => return Ok ( ClientResponse ( None ) ) ,
290
+ EntryPayload :: Normal ( ref norm) => {
291
+ let data = & norm. data ;
292
+ if let Some ( ( serial, res) ) = sm. client_serial_responses . get ( & data. client ) {
293
+ if serial == & data. serial {
294
+ return Ok ( ClientResponse ( res. clone ( ) ) ) ;
295
+ }
296
+ }
297
+ let previous = sm. client_status . insert ( data. client . clone ( ) , data. status . clone ( ) ) ;
298
+ sm. client_serial_responses . insert ( data. client . clone ( ) , ( data. serial , previous. clone ( ) ) ) ;
299
+ Ok ( ClientResponse ( previous) )
286
300
}
287
- }
288
- let previous = sm. client_status . insert ( data. client . clone ( ) , data. status . clone ( ) ) ;
289
- sm. client_serial_responses . insert ( data. client . clone ( ) , ( data. serial , previous. clone ( ) ) ) ;
290
- Ok ( ClientResponse ( previous) )
301
+ EntryPayload :: ConfigChange ( ref mem) => {
302
+ sm. last_membership = Some ( mem. membership . clone ( ) ) ;
303
+ return Ok ( ClientResponse ( None ) ) ;
304
+ }
305
+ } ;
291
306
}
292
307
293
308
#[ tracing:: instrument( level = "trace" , skip( self , entries) ) ]
294
- async fn replicate_to_state_machine ( & self , entries : & [ ( & LogId , & ClientRequest ) ] ) -> Result < ( ) > {
309
+ async fn replicate_to_state_machine ( & self , entries : & [ & Entry < ClientRequest > ] ) -> Result < ( ) > {
295
310
let mut sm = self . sm . write ( ) . await ;
296
- for ( index, data) in entries {
297
- sm. last_applied_log = * * index;
298
- if let Some ( ( serial, _) ) = sm. client_serial_responses . get ( & data. client ) {
299
- if serial == & data. serial {
300
- continue ;
311
+ for entry in entries {
312
+ sm. last_applied_log = entry. log_id ;
313
+
314
+ match entry. payload {
315
+ EntryPayload :: Blank => { }
316
+ EntryPayload :: SnapshotPointer ( _) => { }
317
+ EntryPayload :: Normal ( ref norm) => {
318
+ let data = & norm. data ;
319
+ if let Some ( ( serial, _) ) = sm. client_serial_responses . get ( & data. client ) {
320
+ if serial == & data. serial {
321
+ continue ;
322
+ }
323
+ }
324
+ let previous = sm. client_status . insert ( data. client . clone ( ) , data. status . clone ( ) ) ;
325
+ sm. client_serial_responses . insert ( data. client . clone ( ) , ( data. serial , previous. clone ( ) ) ) ;
301
326
}
302
- }
303
- let previous = sm. client_status . insert ( data. client . clone ( ) , data. status . clone ( ) ) ;
304
- sm. client_serial_responses . insert ( data. client . clone ( ) , ( data. serial , previous. clone ( ) ) ) ;
327
+ EntryPayload :: ConfigChange ( ref mem) => {
328
+ sm. last_membership = Some ( mem. membership . clone ( ) ) ;
329
+ }
330
+ } ;
305
331
}
306
332
Ok ( ( ) )
307
333
}
308
334
309
335
#[ tracing:: instrument( level = "trace" , skip( self ) ) ]
310
336
async fn do_log_compaction ( & self ) -> Result < CurrentSnapshotData < Self :: Snapshot > > {
311
337
let ( data, last_applied_log) ;
338
+ let membership_config;
312
339
{
313
340
// Serialize the data of the state machine.
314
341
let sm = self . sm . read ( ) . await ;
315
342
data = serde_json:: to_vec ( & * sm) ?;
316
343
last_applied_log = sm. last_applied_log ;
344
+ membership_config = sm. last_membership . clone ( ) . unwrap_or_else ( || MembershipConfig :: new_initial ( self . id ) ) ;
317
345
} // Release state machine read lock.
318
346
319
347
let snapshot_size = data. len ( ) ;
320
348
321
- let membership_config = self . get_membership_from_log ( Some ( last_applied_log. index ) ) . await ?;
322
-
323
349
let snapshot_idx = {
324
350
let mut l = self . snapshot_idx . lock ( ) . unwrap ( ) ;
325
351
* l += 1 ;
0 commit comments