Caching resolved addresses

This commit is contained in:
Dennis Schwerdel 2016-08-29 15:20:32 +02:00
parent e0da4a736f
commit c41a49c0b7
2 changed files with 19 additions and 8 deletions

View File

@ -73,7 +73,7 @@ impl PeerList {
} }
#[inline] #[inline]
fn is_connected<Addr: ToSocketAddrs+fmt::Display>(&self, addr: Addr) -> Result<bool, Error> { fn is_connected<Addr: ToSocketAddrs+fmt::Debug>(&self, addr: Addr) -> Result<bool, Error> {
for addr in try!(resolve(addr)) { for addr in try!(resolve(addr)) {
if self.contains_addr(&addr) { if self.contains_addr(&addr) {
return Ok(true); return Ok(true);
@ -155,6 +155,8 @@ impl PeerList {
#[derive(Clone)] #[derive(Clone)]
pub struct ReconnectEntry { pub struct ReconnectEntry {
address: String, address: String,
resolved: Vec<SocketAddr>,
next_resolve: Time,
tries: u16, tries: u16,
timeout: u16, timeout: u16,
next: Time next: Time
@ -300,6 +302,8 @@ impl<P: Protocol> GenericCloud<P> {
address: add, address: add,
tries: 0, tries: 0,
timeout: 1, timeout: 1,
resolved: vec![],
next_resolve: now(),
next: now() next: now()
}) })
} }
@ -309,7 +313,7 @@ impl<P: Protocol> GenericCloud<P> {
/// # Errors /// # Errors
/// Returns an `Error::SocketError` if the given address is a name that failed to resolve to /// Returns an `Error::SocketError` if the given address is a name that failed to resolve to
/// actual addresses. /// actual addresses.
fn is_blacklisted<Addr: ToSocketAddrs+fmt::Display>(&self, addr: Addr) -> Result<bool, Error> { fn is_blacklisted<Addr: ToSocketAddrs+fmt::Debug>(&self, addr: Addr) -> Result<bool, Error> {
for addr in try!(resolve(addr)) { for addr in try!(resolve(addr)) {
if self.blacklist_peers.contains(&addr) { if self.blacklist_peers.contains(&addr) {
return Ok(true); return Ok(true);
@ -326,11 +330,11 @@ impl<P: Protocol> GenericCloud<P> {
/// ///
/// # Errors /// # Errors
/// This method returns `Error::NameError` if the address is a name that fails to resolve. /// This method returns `Error::NameError` if the address is a name that fails to resolve.
pub fn connect<Addr: ToSocketAddrs+fmt::Display+Clone>(&mut self, addr: Addr) -> Result<(), Error> { pub fn connect<Addr: ToSocketAddrs+fmt::Debug+Clone>(&mut self, addr: Addr) -> Result<(), Error> {
if try!(self.peers.is_connected(addr.clone())) || try!(self.is_blacklisted(addr.clone())) { if try!(self.peers.is_connected(addr.clone())) || try!(self.is_blacklisted(addr.clone())) {
return Ok(()) return Ok(())
} }
debug!("Connecting to {}", addr); debug!("Connecting to {:?}", addr);
let subnets = self.addresses.clone(); let subnets = self.addresses.clone();
let node_id = self.node_id; let node_id = self.node_id;
// Send a message to each resolved address // Send a message to each resolved address
@ -385,16 +389,23 @@ impl<P: Protocol> GenericCloud<P> {
if entry.next > now { if entry.next > now {
continue continue
} }
try!(self.connect(&entry.address as &str)); try!(self.connect(&entry.resolved as &[SocketAddr]));
} }
for entry in &mut self.reconnect_peers { for entry in &mut self.reconnect_peers {
// Schedule for next second if node is connected // Schedule for next second if node is connected
if try!(self.peers.is_connected(&entry.address as &str)) { if try!(self.peers.is_connected(&entry.resolved as &[SocketAddr])) {
entry.tries = 0; entry.tries = 0;
entry.timeout = 1; entry.timeout = 1;
entry.next = now + 1; entry.next = now + 1;
continue continue
} }
// Resolve entries anew
if entry.next_resolve <= now {
if let Ok(addrs) = resolve(&entry.address as &str) {
entry.resolved = addrs;
}
entry.next_resolve = now + 60;
}
// Ignore if next attempt is already in the future // Ignore if next attempt is already in the future
if entry.next > now { if entry.next > now {
continue continue

View File

@ -123,8 +123,8 @@ macro_rules! try_fail {
} }
pub fn resolve<Addr: ToSocketAddrs+fmt::Display>(addr: Addr) -> Result<Vec<SocketAddr>, Error> { pub fn resolve<Addr: ToSocketAddrs+fmt::Debug>(addr: Addr) -> Result<Vec<SocketAddr>, Error> {
let addrs = try!(addr.to_socket_addrs().map_err(|_| Error::Name(format!("{}", addr)))); let addrs = try!(addr.to_socket_addrs().map_err(|_| Error::Name(format!("{:?}", addr))));
// Remove duplicates in addrs (why are there duplicates???) // Remove duplicates in addrs (why are there duplicates???)
let mut addrs = addrs.collect::<Vec<_>>(); let mut addrs = addrs.collect::<Vec<_>>();
// Try IPv4 first as it usually is faster // Try IPv4 first as it usually is faster