فهرست منبع

Implement a drop guard.

Jing Yang 5 سال پیش
والد
کامیت
8eca0ab175
2فایلهای تغییر یافته به همراه23 افزوده شده و 1 حذف شده
  1. 7 1
      src/lib.rs
  2. 16 0
      src/utils.rs

+ 7 - 1
src/lib.rs

@@ -17,7 +17,7 @@ use parking_lot::Mutex;
 use rand::{thread_rng, Rng};
 
 use crate::rpcs::RpcClient;
-use crate::utils::retry_rpc;
+use crate::utils::{retry_rpc, DropGuard};
 
 pub mod rpcs;
 mod utils;
@@ -202,6 +202,8 @@ impl Raft {
             };
         }
 
+        let _ = rf.deferred_persist();
+
         if rf.current_term < args.term {
             rf.current_term = args.term;
             rf.voted_for = None;
@@ -590,6 +592,10 @@ impl RaftState {
         // TODO: implement
     }
 
+    fn deferred_persist(&self) -> impl Drop + '_ {
+        DropGuard::new(move || { self.persist() })
+    }
+
     fn last_log_index_and_term(&self) -> (usize, Term) {
         let len = self.log.len();
         assert!(len > 0, "There should always be at least one entry in log");

+ 16 - 0
src/utils.rs

@@ -20,3 +20,19 @@ where
         format!("Timed out after {} retries", max_retry),
     ))
 }
+
+pub struct DropGuard<F: FnOnce() -> ()> {
+    task: Option<F>,
+}
+
+impl<F: FnOnce() -> ()> DropGuard<F> {
+    pub fn new(task: F) -> Self {
+        Self { task: Some(task) }
+    }
+}
+
+impl<F: FnOnce() -> ()> Drop for DropGuard<F> {
+    fn drop(&mut self) {
+        (self.task.take().unwrap())();
+    }
+}