Move peer location query to separate function, optimize location cache
This commit is contained in:
parent
d7b6c54b08
commit
22c682f393
1 changed files with 89 additions and 47 deletions
|
@ -517,66 +517,108 @@ class UiWebsocketPlugin(object):
|
|||
-100
|
||||
])
|
||||
|
||||
def getPeerLocations(self, peers):
|
||||
import maxminddb
|
||||
db_path = config.data_dir + '/GeoLite2-City.mmdb'
|
||||
if not os.path.isfile(db_path) or os.path.getsize(db_path) == 0:
|
||||
if not self.downloadGeoLiteDb(db_path):
|
||||
return False
|
||||
geodb = maxminddb.open_database(db_path)
|
||||
|
||||
peers = peers.values()
|
||||
# Place bars
|
||||
peer_locations = []
|
||||
placed = {} # Already placed bars here
|
||||
for peer in peers:
|
||||
# Height of bar
|
||||
if peer.connection and peer.connection.last_ping_delay:
|
||||
ping = round(peer.connection.last_ping_delay * 1000)
|
||||
else:
|
||||
ping = None
|
||||
|
||||
# Query and cache location
|
||||
if peer.ip in loc_cache:
|
||||
loc = loc_cache[peer.ip]
|
||||
else:
|
||||
try:
|
||||
loc_data = geodb.get(peer.ip)
|
||||
except:
|
||||
loc_data = None
|
||||
if not loc_data or "location" not in loc_data:
|
||||
loc_cache[peer.ip] = None
|
||||
continue
|
||||
|
||||
loc = {
|
||||
"lat": loc_data["location"]["latitude"],
|
||||
"lon": loc_data["location"]["longitude"],
|
||||
}
|
||||
if "city" in loc_data:
|
||||
loc["city"] = loc_data["city"]["names"]["en"]
|
||||
if "country" in loc_data:
|
||||
loc["country"] = loc_data["country"]["names"]["en"]
|
||||
loc_cache[peer.ip] = loc
|
||||
if not loc:
|
||||
continue
|
||||
# Create position array
|
||||
lat, lon = loc["lat"], loc["lon"]
|
||||
latlon = "%s,%s" % (lat, lon)
|
||||
if latlon in placed: # Dont place more than 1 bar to same place, fake repos using ip address last two part
|
||||
lat += float(128 - int(peer.ip.split(".")[-2])) / 50
|
||||
lon += float(128 - int(peer.ip.split(".")[-1])) / 50
|
||||
latlon = "%s,%s" % (lat, lon)
|
||||
placed[latlon] = True
|
||||
peer_location = {}
|
||||
peer_location.update(loc)
|
||||
peer_location["lat"] = lat
|
||||
peer_location["lon"] = lon
|
||||
peer_location["ping"] = ping
|
||||
|
||||
peer_locations.append(peer_location)
|
||||
|
||||
# Append myself
|
||||
try:
|
||||
loc_data = geodb.get(config.ip_external)
|
||||
except:
|
||||
loc_data = None
|
||||
if loc_data and loc_data.get("location"):
|
||||
peer_location = {
|
||||
"lat": loc_data["location"]["latitude"],
|
||||
"lon": loc_data["location"]["longitude"],
|
||||
"country": loc_data["country"]["names"]["en"],
|
||||
"city": loc_data["city"]["names"]["en"],
|
||||
"ping": 0
|
||||
}
|
||||
peer_locations.append(peer_location)
|
||||
|
||||
return peer_locations
|
||||
|
||||
|
||||
def actionSidebarGetPeers(self, to):
|
||||
permissions = self.getPermissions(to)
|
||||
if "ADMIN" not in permissions:
|
||||
return self.response(to, "You don't have permission to run this command")
|
||||
try:
|
||||
import maxminddb
|
||||
db_path = config.data_dir + '/GeoLite2-City.mmdb'
|
||||
if not os.path.isfile(db_path) or os.path.getsize(db_path) == 0:
|
||||
if not self.downloadGeoLiteDb(db_path):
|
||||
return False
|
||||
geodb = maxminddb.open_database(db_path)
|
||||
|
||||
peers = self.site.peers.values()
|
||||
# Find avg ping
|
||||
peer_locations = self.getPeerLocations(self.site.peers)
|
||||
globe_data = []
|
||||
ping_times = [
|
||||
peer.connection.last_ping_delay
|
||||
for peer in peers
|
||||
if peer.connection and peer.connection.last_ping_delay and peer.connection.last_ping_delay
|
||||
peer_location["ping"]
|
||||
for peer_location in peer_locations
|
||||
if peer_location["ping"]
|
||||
]
|
||||
if ping_times:
|
||||
ping_avg = sum(ping_times) / float(len(ping_times))
|
||||
else:
|
||||
ping_avg = 0
|
||||
# Place bars
|
||||
globe_data = []
|
||||
placed = {} # Already placed bars here
|
||||
for peer in peers:
|
||||
# Height of bar
|
||||
if peer.connection and peer.connection.last_ping_delay:
|
||||
ping = min(0.20, math.log(1 + peer.connection.last_ping_delay / ping_avg, 300))
|
||||
|
||||
for peer_location in peer_locations:
|
||||
if peer_location["ping"] == 0: # Me
|
||||
height = -0.135
|
||||
elif peer_location["ping"]:
|
||||
height = min(0.20, math.log(1 + peer_location["ping"] / ping_avg, 300))
|
||||
else:
|
||||
ping = -0.03
|
||||
height = -0.03
|
||||
|
||||
# Query and cache location
|
||||
if peer.ip in loc_cache:
|
||||
loc = loc_cache[peer.ip]
|
||||
else:
|
||||
try:
|
||||
loc = geodb.get(peer.ip)
|
||||
except:
|
||||
loc = None
|
||||
loc_cache[peer.ip] = loc
|
||||
if not loc or "location" not in loc:
|
||||
continue
|
||||
|
||||
# Create position array
|
||||
lat, lon = (loc["location"]["latitude"], loc["location"]["longitude"])
|
||||
latlon = "%s,%s" % (lat, lon)
|
||||
if latlon in placed: # Dont place more than 1 bar to same place, fake repos using ip address last two part
|
||||
lat += float(128 - int(peer.ip.split(".")[-2])) / 50
|
||||
lon += float(128 - int(peer.ip.split(".")[-1])) / 50
|
||||
latlon = "%s,%s" % (lat, lon)
|
||||
placed[latlon] = True
|
||||
|
||||
globe_data += (lat, lon, ping)
|
||||
# Append myself
|
||||
loc = geodb.get(config.ip_external)
|
||||
if loc and loc.get("location"):
|
||||
lat, lon = (loc["location"]["latitude"], loc["location"]["longitude"])
|
||||
globe_data += (lat, lon, -0.135)
|
||||
globe_data += [peer_location["lat"], peer_location["lon"], height]
|
||||
|
||||
self.response(to, globe_data)
|
||||
except Exception, err:
|
||||
|
|
Loading…
Reference in a new issue