Explorar o código

Use error kind "interrupted" when the server is removed.

Jing Yang %!s(int64=3) %!d(string=hai) anos
pai
achega
bfb8ed2ea1
Modificáronse 2 ficheiros con 29 adicións e 3 borrados
  1. 3 1
      src/network.rs
  2. 26 2
      src/server.rs

+ 3 - 1
src/network.rs

@@ -92,6 +92,8 @@ impl Network {
 
     pub fn remove_server<S: AsRef<str>>(&mut self, server_name: S) {
         let server = self.servers.remove(server_name.as_ref());
+        // Note: Requests received before the removal, but has not yet started
+        // waiting on the server to return might fall through the crack.
         if let Some(server) = server {
             server.interrupt();
         }
@@ -530,7 +532,7 @@ mod tests {
         let err = reply
             .expect_err("Client should receive error after server is killed");
         assert!(
-            std::io::ErrorKind::ConnectionReset == err.kind()
+            std::io::ErrorKind::Interrupted == err.kind()
                 || std::io::ErrorKind::NotFound == err.kind()
         );
 

+ 26 - 2
src/server.rs

@@ -120,14 +120,15 @@ impl Server {
         let ret = match result {
             Some(Ok(ret)) => ret,
             Some(Err(_)) => Err(std::io::Error::new(
+                // The future panicked or was cancelled in the thread pool.
                 std::io::ErrorKind::ConnectionReset,
                 format!("Remote server {} cancelled the RPC.", this.name),
             )),
             None => {
                 // Fail the RPC if the server has been terminated.
                 Err(std::io::Error::new(
-                    std::io::ErrorKind::ConnectionReset,
-                    "Network connection has been reset.".to_owned(),
+                    std::io::ErrorKind::Interrupted,
+                    "The server has been forced to shutdown.".to_owned(),
                 ))
             }
         };
@@ -300,6 +301,29 @@ mod tests {
         Ok(())
     }
 
+    #[test]
+    fn test_serve_interrupted() -> Result<()> {
+        let server = make_arc_test_server();
+        // We cannot use `notify_waiters()` because it requires that tasks are
+        // already waiting when this function is called.
+        server.interrupt.notify_one();
+
+        let reply = dispatch(
+            server,
+            "echo".to_string(),
+            RequestMessage::from_static(&[0x08, 0x07]),
+        );
+
+        assert_eq!(
+            reply
+                .err()
+                .expect("Interrupted server should return error")
+                .kind(),
+            std::io::ErrorKind::Interrupted,
+        );
+        Ok(())
+    }
+
     #[test]
     fn test_server_survives_30_rpc_errors() -> Result<()> {
         let server = make_arc_test_server();