@@ -216,6 +216,7 @@ impl WorkloadState {
216
216
}
217
217
218
218
fn rollback ( & mut self , snapshot : Snapshot ) {
219
+ // The application of a rollback counts as increased sync_seq.
219
220
self . committed . sync_seqn += 1 ;
220
221
self . committed . state = snapshot. state ;
221
222
}
@@ -246,8 +247,8 @@ pub struct Workload {
246
247
workload_id : u64 ,
247
248
/// The seed for bitbox generated for this workload.
248
249
bitbox_seed : [ u8 ; 16 ] ,
249
- /// Data collected to evaluate the average commit time in nanoseconds .
250
- tot_commit_time : u64 ,
250
+ /// Data collected to evaluate the average commit time.
251
+ tot_commit_time : Duration ,
251
252
n_successfull_commit : u64 ,
252
253
/// Whether to ensure the correct application of the changeset after every commit.
253
254
ensure_changeset : bool ,
@@ -257,18 +258,9 @@ pub struct Workload {
257
258
sample_snapshot : bool ,
258
259
/// The max number of commits involved in a rollback.
259
260
max_rollback_commits : u32 ,
260
- /// If `Some` there are rollbacks waiting to be applied.
261
- scheduled_rollbacks : ScheduledRollbacks ,
262
- }
263
-
264
- /// Tracker of rollbacks waiting for being applied.
265
- struct ScheduledRollbacks {
266
- /// If `Some` there is rollback waiting to be applied.
267
- rollback : Option < ScheduledRollback > ,
268
261
/// If `Some` there is rollback waiting to be applied,
269
- /// alongside the delay after which the rollback process should panic,
270
- /// measured in nanoseconds.
271
- rollback_crash : Option < ( ScheduledRollback , u64 ) > ,
262
+ /// possibly alongside the delay after which the rollback process should panic.
263
+ scheduled_rollback : Option < ( ScheduledRollback , Option < Duration > ) > ,
272
264
}
273
265
274
266
/// Contains the information required to apply a rollback.
@@ -317,16 +309,13 @@ impl Workload {
317
309
state,
318
310
workload_id,
319
311
bitbox_seed,
320
- tot_commit_time : 0 ,
312
+ tot_commit_time : Duration :: ZERO ,
321
313
n_successfull_commit : 0 ,
322
314
ensure_changeset : workload_params. ensure_changeset ,
323
315
ensure_snapshot : workload_params. ensure_snapshot ,
324
316
sample_snapshot : workload_params. sample_snapshot ,
325
317
max_rollback_commits : workload_params. max_rollback_commits ,
326
- scheduled_rollbacks : ScheduledRollbacks {
327
- rollback : None ,
328
- rollback_crash : None ,
329
- } ,
318
+ scheduled_rollback : None ,
330
319
}
331
320
}
332
321
@@ -360,28 +349,20 @@ impl Workload {
360
349
let rr = agent. rr ( ) . clone ( ) ;
361
350
trace ! ( "run_iteration" ) ;
362
351
363
- if let Some ( ( scheduled_rollback, should_crash) ) = self
364
- . scheduled_rollbacks
365
- . is_time ( self . state . committed . sync_seqn )
366
- {
352
+ if self . scheduled_rollback . as_ref ( ) . map_or ( false , |( r, _) | {
353
+ r. sync_seqn == self . state . committed . sync_seqn
354
+ } ) {
355
+ // UNWRAP: scheduled_rollback has just be checked to be `Some`
356
+ let ( scheduled_rollback, should_crash) = self . scheduled_rollback . take ( ) . unwrap ( ) ;
367
357
self . perform_scheduled_rollback ( & rr, scheduled_rollback, should_crash)
368
358
. await ?;
369
359
return Ok ( ( ) ) ;
370
360
}
371
361
372
362
// Do not schedule new rollbacks if they are already scheduled.
373
- let mut rollback = self . state . biases . rollback ;
374
- if self . scheduled_rollbacks . is_rollback_scheduled ( ) {
375
- rollback = 0.0 ;
376
- }
377
-
378
- let mut rollback_crash = self . state . biases . rollback_crash ;
379
- if self . scheduled_rollbacks . is_rollback_crash_scheduled ( ) {
380
- rollback_crash = 0.0 ;
381
- }
382
-
383
- if self . state . rng . gen_bool ( rollback) {
384
- if self . state . rng . gen_bool ( rollback_crash) {
363
+ let is_rollback_scheduled = self . scheduled_rollback . is_some ( ) ;
364
+ if !is_rollback_scheduled && self . state . rng . gen_bool ( self . state . biases . rollback ) {
365
+ if self . state . rng . gen_bool ( self . state . biases . rollback_crash ) {
385
366
self . schedule_rollback ( true /*should_crash*/ ) . await ?
386
367
} else {
387
368
self . schedule_rollback ( false /*should_crash*/ ) . await ?
@@ -437,19 +418,20 @@ impl Workload {
437
418
438
419
// The agent should crash after `crash_delay`ns.
439
420
// If no data avaible crash after 300ms.
440
- let mut crash_delay = self
421
+ let mut crash_delay_millis = self
441
422
. tot_commit_time
442
- . checked_div ( self . n_successfull_commit )
443
- . unwrap_or ( Duration :: from_millis ( 300 ) . as_nanos ( ) as u64 ) ;
423
+ . as_millis ( )
424
+ . checked_div ( self . n_successfull_commit as u128 )
425
+ . unwrap_or ( 300 ) as u64 ;
444
426
// Crash a little bit earlier than the average commit time to increase the
445
427
// possibilities of crashing during sync.
446
- crash_delay = ( crash_delay as f64 * 0.98 ) as u64 ;
428
+ crash_delay_millis = ( crash_delay_millis as f64 * 0.98 ) as u64 ;
447
429
448
430
trace ! ( "exercising commit crash" ) ;
449
431
rr. send_request ( crate :: message:: ToAgent :: Commit (
450
432
crate :: message:: CommitPayload {
451
433
changeset : changeset. clone ( ) ,
452
- should_crash : Some ( crash_delay ) ,
434
+ should_crash : Some ( Duration :: from_millis ( crash_delay_millis ) ) ,
453
435
} ,
454
436
) )
455
437
. await ?;
@@ -478,10 +460,6 @@ impl Workload {
478
460
479
461
async fn schedule_rollback ( & mut self , should_crash : bool ) -> anyhow:: Result < ( ) > {
480
462
let n_commits_to_rollback = self . state . rng . gen_range ( 1 ..self . max_rollback_commits ) as usize ;
481
- if n_commits_to_rollback == 0 {
482
- trace ! ( "No available commits to perform rollback with" ) ;
483
- return Ok ( ( ) ) ;
484
- }
485
463
486
464
let last_snapshot = & self . state . committed ;
487
465
let rollback_sync_seqn = last_snapshot. sync_seqn + n_commits_to_rollback as u32 ;
@@ -491,14 +469,15 @@ impl Workload {
491
469
snapshot : last_snapshot. clone ( ) ,
492
470
} ;
493
471
494
- if should_crash {
472
+ let maybe_crash_delay = if should_crash {
495
473
// TODO: more complex crash delay evaluation for rollbacks.
496
- let crash_delay = Duration :: from_millis ( 10 ) . as_nanos ( ) as u64 ;
497
- self . scheduled_rollbacks . rollback_crash = Some ( ( scheduled_rollback, crash_delay) ) ;
474
+ Some ( Duration :: from_millis ( 10 ) )
498
475
} else {
499
- self . scheduled_rollbacks . rollback = Some ( scheduled_rollback ) ;
476
+ None
500
477
} ;
501
478
479
+ self . scheduled_rollback = Some ( ( scheduled_rollback, maybe_crash_delay) ) ;
480
+
502
481
trace ! (
503
482
"scheduled rollback {}for sync_seqn: {} of {} commits" ,
504
483
if should_crash { "crash " } else { "" } ,
@@ -513,7 +492,7 @@ impl Workload {
513
492
& mut self ,
514
493
rr : & comms:: RequestResponse ,
515
494
scheduled_rollback : ScheduledRollback ,
516
- should_crash : Option < u64 > ,
495
+ should_crash : Option < Duration > ,
517
496
) -> anyhow:: Result < ( ) > {
518
497
let ScheduledRollback {
519
498
n_commits,
@@ -560,7 +539,7 @@ impl Workload {
560
539
rr : & comms:: RequestResponse ,
561
540
n_commits_to_rollback : usize ,
562
541
snapshot : Snapshot ,
563
- crash_delay : u64 ,
542
+ crash_delay : Duration ,
564
543
) -> anyhow:: Result < ( ) > {
565
544
trace ! (
566
545
"exercising rollback crash of {} commits" ,
@@ -778,47 +757,3 @@ impl Workload {
778
757
self . workdir
779
758
}
780
759
}
781
-
782
- impl ScheduledRollbacks {
783
- fn is_time ( & mut self , curr_sync_seqn : u32 ) -> Option < ( ScheduledRollback , Option < u64 > ) > {
784
- if self
785
- . rollback
786
- . as_ref ( )
787
- . map_or ( false , |ScheduledRollback { sync_seqn, .. } | {
788
- curr_sync_seqn == * sync_seqn
789
- } )
790
- {
791
- // UNWRAP: self.rollback has just been checked to be Some.
792
- let scheduled_rollback = self . rollback . take ( ) . unwrap ( ) ;
793
-
794
- // The probability of having scheduled at the same time both a rollback and
795
- // a rollback crash is very low, but if it happens, only the rollback will be applied.
796
- // Discard the rollback crash data.
797
- let _ = self . is_time ( curr_sync_seqn) ;
798
-
799
- return Some ( ( scheduled_rollback, None ) ) ;
800
- }
801
-
802
- if self
803
- . rollback_crash
804
- . as_ref ( )
805
- . map_or ( false , |( ScheduledRollback { sync_seqn, .. } , _) | {
806
- curr_sync_seqn == * sync_seqn
807
- } )
808
- {
809
- // UNWRAP: self.rollback has just been checked to be Some.
810
- let ( scheduled_rollback, crash_delay) = self . rollback_crash . take ( ) . unwrap ( ) ;
811
- return Some ( ( scheduled_rollback, Some ( crash_delay) ) ) ;
812
- }
813
-
814
- return None ;
815
- }
816
-
817
- fn is_rollback_scheduled ( & self ) -> bool {
818
- self . rollback . is_some ( )
819
- }
820
-
821
- fn is_rollback_crash_scheduled ( & self ) -> bool {
822
- self . rollback_crash . is_some ( )
823
- }
824
- }
0 commit comments