Redesign Site.needConnections()
This commit is contained in:
parent
3ca323f8b0
commit
511a90a5c5
3 changed files with 80 additions and 26 deletions
|
@ -295,12 +295,12 @@ class FileServer(ConnectionServer):
|
||||||
elif site.bad_files:
|
elif site.bad_files:
|
||||||
site.retryBadFiles()
|
site.retryBadFiles()
|
||||||
|
|
||||||
if time.time() - site.settings.get("modified", 0) < 60 * 60 * 24 * 7:
|
# Keep active connections
|
||||||
# Keep active connections if site has been modified witin 7 days
|
connected_num = site.needConnections(check_site_on_reconnect=True)
|
||||||
connected_num = site.needConnections(check_site_on_reconnect=True)
|
|
||||||
|
|
||||||
if connected_num < config.connected_limit: # This site has small amount of peers, protect them from closing
|
if connected_num < config.connected_limit:
|
||||||
peers_protected.update([peer.key for peer in site.getConnectedPeers()])
|
# This site has small amount of peers, protect them from closing
|
||||||
|
peers_protected.update([peer.key for peer in site.getConnectedPeers()])
|
||||||
|
|
||||||
time.sleep(1) # Prevent too quick request
|
time.sleep(1) # Prevent too quick request
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,9 @@ class Peer(object):
|
||||||
|
|
||||||
logger.log(self.log_level, "%s:%s %s" % (self.ip, self.port, text))
|
logger.log(self.log_level, "%s:%s %s" % (self.ip, self.port, text))
|
||||||
|
|
||||||
|
def isConnected(self):
|
||||||
|
return self.connection and self.connection.connected
|
||||||
|
|
||||||
# Connect to host
|
# Connect to host
|
||||||
def connect(self, connection=None):
|
def connect(self, connection=None):
|
||||||
if self.reputation < -10:
|
if self.reputation < -10:
|
||||||
|
@ -249,11 +252,11 @@ class Peer(object):
|
||||||
return buff
|
return buff
|
||||||
|
|
||||||
# Send a ping request
|
# Send a ping request
|
||||||
def ping(self):
|
def ping(self, timeout=10.0, tryes=3):
|
||||||
response_time = None
|
response_time = None
|
||||||
for retry in range(1, 3): # Retry 3 times
|
for retry in range(1, tryes): # Retry 3 times
|
||||||
s = time.time()
|
s = time.time()
|
||||||
with gevent.Timeout(10.0, False): # 10 sec timeout, don't raise exception
|
with gevent.Timeout(timeout, False):
|
||||||
res = self.request("ping")
|
res = self.request("ping")
|
||||||
|
|
||||||
if res and "body" in res and res["body"] == b"Pong!":
|
if res and "body" in res and res["body"] == b"Pong!":
|
||||||
|
|
|
@ -853,36 +853,87 @@ class Site(object):
|
||||||
if self.isServing():
|
if self.isServing():
|
||||||
self.announcer.announce(*args, **kwargs)
|
self.announcer.announce(*args, **kwargs)
|
||||||
|
|
||||||
# Keep connections to get the updates
|
def getPreferableActiveConnectionCount(self):
|
||||||
def needConnections(self, num=None, check_site_on_reconnect=False):
|
if not self.isServing():
|
||||||
if num is None:
|
return 0
|
||||||
if len(self.peers) < 50:
|
|
||||||
num = 3
|
|
||||||
else:
|
|
||||||
num = 6
|
|
||||||
need = min(len(self.peers), num, config.connected_limit) # Need 5 peer, but max total peers
|
|
||||||
|
|
||||||
|
age = time.time() - self.settings.get("modified", 0)
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
if age < 60 * 60:
|
||||||
|
count = 10
|
||||||
|
elif age < 60 * 60 * 5:
|
||||||
|
count = 8
|
||||||
|
elif age < 60 * 60 * 24:
|
||||||
|
count = 6
|
||||||
|
elif age < 60 * 60 * 24 * 3:
|
||||||
|
count = 4
|
||||||
|
elif age < 60 * 60 * 24 * 7:
|
||||||
|
count = 2
|
||||||
|
|
||||||
|
if len(self.peers) < 50:
|
||||||
|
count = max(count, 5)
|
||||||
|
|
||||||
|
return count
|
||||||
|
|
||||||
|
def tryConnectingToMorePeers(self, more=1, pex=True, try_harder=False):
|
||||||
|
max_peers = more * 2 + 10
|
||||||
|
if try_harder:
|
||||||
|
max_peers += 10000
|
||||||
|
|
||||||
|
connected = 0
|
||||||
|
for peer in self.getRecentPeers(max_peers):
|
||||||
|
if not peer.isConnected():
|
||||||
|
if pex:
|
||||||
|
peer.pex()
|
||||||
|
else:
|
||||||
|
peer.ping(timeout=2.0, tryes=1)
|
||||||
|
|
||||||
|
if peer.isConnected():
|
||||||
|
connected += 1
|
||||||
|
|
||||||
|
if connected >= more:
|
||||||
|
break
|
||||||
|
|
||||||
|
return connected
|
||||||
|
|
||||||
|
def bringConnections(self, need=1, check_site_on_reconnect=False, pex=True, try_harder=False):
|
||||||
connected = len(self.getConnectedPeers())
|
connected = len(self.getConnectedPeers())
|
||||||
|
|
||||||
connected_before = connected
|
connected_before = connected
|
||||||
|
|
||||||
self.log.debug("Need connections: %s, Current: %s, Total: %s" % (need, connected, len(self.peers)))
|
self.log.debug("Need connections: %s, Current: %s, Total: %s" % (need, connected, len(self.peers)))
|
||||||
|
|
||||||
if connected < need: # Need more than we have
|
if connected < need:
|
||||||
for peer in self.getRecentPeers(30):
|
connected += self.tryConnectingToMorePeers(more=(need-connected), pex=pex, try_harder=try_harder)
|
||||||
if not peer.connection or not peer.connection.connected: # No peer connection or disconnected
|
|
||||||
peer.pex() # Initiate peer exchange
|
|
||||||
if peer.connection and peer.connection.connected:
|
|
||||||
connected += 1 # Successfully connected
|
|
||||||
if connected >= need:
|
|
||||||
break
|
|
||||||
self.log.debug(
|
self.log.debug(
|
||||||
"Connected before: %s, after: %s. Check site: %s." %
|
"Connected before: %s, after: %s. Check site: %s." %
|
||||||
(connected_before, connected, check_site_on_reconnect)
|
(connected_before, connected, check_site_on_reconnect)
|
||||||
)
|
)
|
||||||
|
|
||||||
if check_site_on_reconnect and connected_before == 0 and connected > 0 and self.connection_server.has_internet:
|
if check_site_on_reconnect and connected_before == 0 and connected > 0 and self.connection_server.has_internet:
|
||||||
gevent.spawn(self.update, check_files=False)
|
self.greenlet_manager.spawn(self.update, check_files=False)
|
||||||
|
|
||||||
|
return connected
|
||||||
|
|
||||||
|
# Keep connections
|
||||||
|
def needConnections(self, num=None, check_site_on_reconnect=False, pex=True):
|
||||||
|
if num is None:
|
||||||
|
num = self.getPreferableActiveConnectionCount()
|
||||||
|
|
||||||
|
need = min(len(self.peers), num, config.connected_limit)
|
||||||
|
|
||||||
|
connected = self.bringConnections(
|
||||||
|
need=need,
|
||||||
|
check_site_on_reconnect=check_site_on_reconnect,
|
||||||
|
pex=pex,
|
||||||
|
try_harder=False)
|
||||||
|
|
||||||
|
if connected < need:
|
||||||
|
self.greenlet_manager.spawnLater(1.0, self.bringConnections,
|
||||||
|
need=need,
|
||||||
|
check_site_on_reconnect=check_site_on_reconnect,
|
||||||
|
pex=pex,
|
||||||
|
try_harder=True)
|
||||||
|
|
||||||
return connected
|
return connected
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue