Repository: AlexPikalov/cdrs (language: rust)

Issue:
ConnectionManager fails to reconnect after Cassandra restart
To reproduce restart local server while running following program:
```rust
extern crate cdrs;
extern crate r2d2;

use std::thread::sleep;
use std::time::Duration;

use cdrs::transport::TransportTcp;
use cdrs::compression::Compression;
use cdrs::authenticators::NoneAuthenticator;
use cdrs::connection_manager::ConnectionManager;

use r2d2::ManageConnection;

fn main() {
    let transport = TransportTcp::new("localhost:9042").expect("Failed to connect");
    let manager = ConnectionManager::new(transport, NoneAuthenticator, Compression::None);

    let mut connection = manager.connect().expect("Failed to connect");
    loop {
        let is_valid = manager.is_valid(&mut connection);
        println!("{:?}", is_valid);
        sleep(Duration::from_secs(1));
        if let Ok(_) = is_valid {
            continue;
        }

        match manager.connect() {
            Ok(conn) => { connection = conn; },
            Err(err) => {
                println!("Failed to reconnect: {:?}", err)
            }
        }
    }
}
```

When creating new connection `ConnectionManager` clones transport. `TransportTcp` uses `peer_addr()` to determine server address. But underlying TCP socket fails `getpeername()` due to not being connected.


Discussion / hints:
@zrkn Thanks for reporting!

Fix patch:
diff --git a/examples/.gitignore b/examples/.gitignore
new file mode 100644
index 0000000..e613873
--- /dev/null
+++ b/examples/.gitignore
@@ -0,0 +1,1 @@
+development.rs
diff --git a/src/transport.rs b/src/transport.rs
index eff7f47..1d43d26 100644
--- a/src/transport.rs
+++ b/src/transport.rs
@@ -60,6 +60,7 @@ pub trait CDRSTransport: Sized + Read + Write + Send + Sync {
 /// Default Tcp transport.
 pub struct TransportTcp {
     tcp: TcpStream,
+    addr: String,
 }
 
 impl TransportTcp {
@@ -73,7 +74,12 @@ impl TransportTcp {
     /// let tcp_transport = TransportTcp::new(addr).unwrap();
     /// ```
     pub fn new(addr: &str) -> io::Result<TransportTcp> {
-        TcpStream::connect(addr).map(|socket| TransportTcp { tcp: socket })
+        TcpStream::connect(addr).map(|socket| {
+                                         TransportTcp {
+                                             tcp: socket,
+                                             addr: addr.to_string(),
+                                         }
+                                     })
     }
 }
 
@@ -95,8 +101,12 @@ impl Write for TransportTcp {
 
 impl CDRSTransport for TransportTcp {
     fn try_clone(&self) -> io::Result<TransportTcp> {
-        let addr = try!(self.tcp.peer_addr());
-        TcpStream::connect(addr).map(|socket| TransportTcp { tcp: socket })
+        TcpStream::connect(self.addr.as_str()).map(|socket| {
+                                                       TransportTcp {
+                                                           tcp: socket,
+                                                           addr: self.addr.clone(),
+                                                       }
+                                                   })
     }
 
     fn close(&mut self, close: net::Shutdown) -> io::Result<()> {
@@ -115,6 +125,7 @@ impl CDRSTransport for TransportTcp {
 pub struct TransportTls {
     ssl: SslStream<TcpStream>,
     connector: SslConnector,
+    addr: String,
 }
 #[cfg(feature = "ssl")]
 impl TransportTls {
@@ -125,6 +136,7 @@ impl TransportTls {
                                                     TransportTls {
                                                         ssl: sslsocket,
                                                         connector: connector.clone(),
+                                                        addr: addr.to_string(),
                                                     }
                                                 })
         });
@@ -160,18 +172,22 @@ impl CDRSTransport for TransportTls {
     /// of a peer from `TransportTls` and creates a new encrypted
     /// connection with a new TCP stream under hood.
     fn try_clone(&self) -> io::Result<TransportTls> {
-        let addr = try!(self.ssl.get_ref().peer_addr());
-        let ip_string = format!("{}", addr.ip());
-
-        let res = net::TcpStream::connect(addr).map(|socket| {
-            self.connector
-                .connect(ip_string.as_str(), socket)
-                .map(|sslsocket| {
-                         TransportTls {
-                             ssl: sslsocket,
-                             connector: self.connector.clone(),
-                         }
-                     })
+        let ip = match self.addr.split(":").nth(0) {
+            Some(_ip) => _ip,
+            None => {
+                return Err(io::Error::new(io::ErrorKind::Other,
+                                          "Wrong addess string - IP is missed"))
+            }
+        };
+
+        let res = net::TcpStream::connect(self.addr.as_str()).map(|socket| {
+            self.connector.connect(ip, socket).map(|sslsocket| {
+                                                       TransportTls {
+                                                           ssl: sslsocket,
+                                                           connector: self.connector.clone(),
+                                                           addr: self.addr.clone(),
+                                                       }
+                                                   })
         });
 
         res.and_then(|res| {


Test patch: