network: introduce NUM_STICKY_SERVERS
This commit is contained in:
@@ -72,6 +72,7 @@ _logger = get_logger(__name__)
|
||||
|
||||
|
||||
NUM_TARGET_CONNECTED_SERVERS = 10
|
||||
NUM_STICKY_SERVERS = 4
|
||||
NUM_RECENT_SERVERS = 20
|
||||
MAX_RETRY_DELAY_FOR_SERVERS = 600 # sec
|
||||
INIT_RETRY_DELAY_FOR_SERVERS = 15 # sec
|
||||
@@ -551,20 +552,27 @@ class Network(Logger):
|
||||
def _get_next_server_to_try(self) -> Optional[ServerAddr]:
|
||||
now = time.time()
|
||||
with self.interfaces_lock:
|
||||
exclude_set = set(self.interfaces) | self.connecting
|
||||
# first try from recent servers
|
||||
connected_servers = set(self.interfaces) | self.connecting
|
||||
# First try from recent servers. (which are persisted)
|
||||
# As these are servers we successfully connected to recently, they are
|
||||
# most likely to work. This also makes servers "sticky".
|
||||
# Note: with sticky servers, it is more difficult for an attacker to eclipse the client,
|
||||
# however if they succeed, the eclipsing would persist. To try to balance this,
|
||||
# we only give priority to recent_servers up to NUM_STICKY_SERVERS.
|
||||
with self.recent_servers_lock:
|
||||
recent_servers = list(self._recent_servers)
|
||||
recent_servers = [s for s in recent_servers if s.protocol == self.protocol]
|
||||
for server in recent_servers:
|
||||
if server in exclude_set:
|
||||
continue
|
||||
if not self._can_retry_server(server, now=now):
|
||||
continue
|
||||
return server
|
||||
# try all servers we know about
|
||||
if len(connected_servers & set(recent_servers)) < NUM_STICKY_SERVERS:
|
||||
for server in recent_servers:
|
||||
if server in connected_servers:
|
||||
continue
|
||||
if not self._can_retry_server(server, now=now):
|
||||
continue
|
||||
return server
|
||||
# try all servers we know about, pick one at random
|
||||
hostmap = self.get_servers()
|
||||
servers = set(filter_protocol(hostmap, self.protocol)) - exclude_set
|
||||
servers = list(set(filter_protocol(hostmap, self.protocol)) - connected_servers)
|
||||
random.shuffle(servers)
|
||||
for server in servers:
|
||||
if not self._can_retry_server(server, now=now):
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user