Jelajahi Sumber

Second attemp to fix `kill()`.

Jing Yang 4 tahun lalu
induk
melakukan
77e3191df8
3 mengubah file dengan 18 tambahan dan 16 penghapusan
  1. 6 2
      kvraft/src/server.rs
  2. 6 9
      kvraft/src/testing_utils/config.rs
  3. 6 5
      kvraft/tests/service_test.rs

+ 6 - 2
kvraft/src/server.rs

@@ -369,8 +369,12 @@ impl KVServer {
         self.rf.lock().clone()
     }
 
-    pub fn kill(self) {
-        self.rf.into_inner().kill()
+    pub fn kill(self: Arc<Self>) {
+        let rf = self.raft();
+        // We must drop self to remove the only clone of raft, so that
+        // `rf.kill()` does not block.
+        drop(self);
+        rf.kill();
         // The process_command thread will exit, after Raft drops the reference
         // to the sender.
     }

+ 6 - 9
kvraft/src/testing_utils/config.rs

@@ -23,7 +23,7 @@ pub struct Config {
     network: Arc<Mutex<labrpc::Network>>,
     server_count: usize,
     state: Mutex<ConfigState>,
-    storage: MemoryStorage,
+    storage: Mutex<MemoryStorage>,
     maxraftstate: usize,
 }
 
@@ -56,7 +56,7 @@ impl Config {
             }
         }
 
-        let persister = self.storage.at(index);
+        let persister = self.storage.lock().at(index);
 
         let kv = KVServer::new(clients, index, persister);
         self.state.lock().kv_servers[index].replace(kv.clone());
@@ -192,14 +192,10 @@ impl Config {
         }
         network.stop();
         drop(network);
+
         for kv_server in &mut self.state.lock().kv_servers {
-            if let Some(kv) = kv_server.take() {
-                match Arc::try_unwrap(kv) {
-                    Ok(kv) => kv.kill(),
-                    Err(_) => panic!(
-                        "All references to KVServer should have been dropped"
-                    ),
-                }
+            if let Some(kv_server) = kv_server.take() {
+                kv_server.kill();
             }
         }
     }
@@ -226,6 +222,7 @@ pub fn make_config(
     for _ in 0..server_count {
         storage.make();
     }
+    let storage = Mutex::new(storage);
 
     let cfg = Config {
         network,

+ 6 - 5
kvraft/tests/service_test.rs

@@ -253,11 +253,12 @@ fn unreliable_one_key_many_clients() -> anyhow::Result<()> {
 
     const CLIENTS: usize = 5;
     const ATTEMPTS: usize = 10;
-    let client_results = spawn_clients(cfg, CLIENTS, |index, mut clerk| {
-        for i in 0..ATTEMPTS {
-            clerk.append("k", format!("({}, {})", index, i));
-        }
-    });
+    let client_results =
+        spawn_clients(cfg.clone(), CLIENTS, |index, mut clerk| {
+            for i in 0..ATTEMPTS {
+                clerk.append("k", format!("({}, {})", index, i));
+            }
+        });
     for client_result in client_results {
         client_result.join().expect("Client should never fail");
     }