use a short timeout when opening the connection to possible peers ()

* use a short timeout when opening the connection to possible peers
lots of peers in the db are unavailable and we do not want to wait 60s for these

* also randomize peers so we don't always try and connect to peers with low ip addresses

* bump timeout up to 5s for peering
This commit is contained in:
AntiochP 2017-11-17 20:13:49 -05:00 committed by GitHub
parent 2e87f40b91
commit 90012c86ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 17 deletions
grin/src
p2p/src

View file

@ -22,6 +22,7 @@ use std::net::SocketAddr;
use std::str::{self, FromStr}; use std::str::{self, FromStr};
use std::sync::Arc; use std::sync::Arc;
use std::time; use std::time;
use std::time::Duration;
use cpupool; use cpupool;
use futures::{self, future, Future, Stream}; use futures::{self, future, Future, Stream};
@ -117,7 +118,7 @@ impl Seeder {
if peers.len() > 0 { if peers.len() > 0 {
debug!( debug!(
LOGGER, LOGGER,
"Got {} more peers from db, trying to connect.", "Got {} peers from db, trying to connect.",
peers.len() peers.len()
); );
thread_rng().shuffle(&mut peers[..]); thread_rng().shuffle(&mut peers[..]);
@ -274,7 +275,11 @@ fn connect_and_req(
h: reactor::Handle, h: reactor::Handle,
addr: SocketAddr, addr: SocketAddr,
) -> Box<Future<Item = (), Error = ()>> { ) -> Box<Future<Item = (), Error = ()>> {
let fut = p2p.connect_peer(addr, h).then(move |p| { let connect_peer = p2p.connect_peer(addr, h).map_err(|_| ());
let timer = Timer::default();
let timeout = timer.timeout(connect_peer, Duration::from_secs(5));
let fut = timeout.then(move |p| {
match p { match p {
Ok(Some(p)) => { Ok(Some(p)) => {
let peer_result = p.send_peer_request(capab); let peer_result = p.send_peer_request(capab);
@ -283,8 +288,7 @@ fn connect_and_req(
Err(_) => {} Err(_) => {}
} }
} }
Err(e) => { Err(_) => {
error!(LOGGER, "Peer request error: {:?}", e);
let update_result = peer_store.update_state(addr, p2p::State::Defunct); let update_result = peer_store.update_state(addr, p2p::State::Defunct);
match update_result { match update_result {
Ok(()) => {} Ok(()) => {}

View file

@ -16,6 +16,7 @@
use std::net::SocketAddr; use std::net::SocketAddr;
use num::FromPrimitive; use num::FromPrimitive;
use rand::{thread_rng, Rng};
use core::ser::{self, Readable, Reader, Writeable, Writer}; use core::ser::{self, Readable, Reader, Writeable, Writer};
use grin_store::{self, option_to_not_found, to_key, Error}; use grin_store::{self, option_to_not_found, to_key, Error};
@ -38,7 +39,7 @@ enum_from_primitive! {
} }
/// Data stored for any given peer we've encountered. /// Data stored for any given peer we've encountered.
#[derive(Debug, Serialize)] #[derive(Debug, Clone, Serialize)]
pub struct PeerData { pub struct PeerData {
/// Network address of the peer. /// Network address of the peer.
pub addr: SocketAddr, pub addr: SocketAddr,
@ -118,18 +119,12 @@ impl PeerStore {
} }
pub fn find_peers(&self, state: State, cap: Capabilities, count: usize) -> Vec<PeerData> { pub fn find_peers(&self, state: State, cap: Capabilities, count: usize) -> Vec<PeerData> {
let peers_iter = self.db let mut peers = self.db
.iter::<PeerData>(&to_key(PEER_PREFIX, &mut "".to_string().into_bytes())); .iter::<PeerData>(&to_key(PEER_PREFIX, &mut "".to_string().into_bytes()))
let mut peers = Vec::with_capacity(count); .filter(|p| p.flags == state && p.capabilities.contains(cap))
for p in peers_iter { .collect::<Vec<_>>();
if p.flags == state && p.capabilities.contains(cap) { thread_rng().shuffle(&mut peers[..]);
peers.push(p); peers.iter().take(count).cloned().collect()
}
if peers.len() >= count {
break;
}
}
peers
} }
/// List all known peers (for the /v1/peers api endpoint) /// List all known peers (for the /v1/peers api endpoint)