Rev536, Fix stats page, Support ranged http requests for better video browser compatibility, setHashfield command, One by one send hashfield to connected peers if changed, Keep count hashfield changetime, PeerHashfield optimalizations, Wait for peers on checkmodification, Give more time to query trackers, Do not count udp trackers as error if udp disabled, Test hashfield push

This commit is contained in:
HelloZeroNet 2015-10-30 02:08:02 +01:00
parent 9c5fda6ed2
commit 8e710beab1
9 changed files with 171 additions and 40 deletions

View file

@ -17,7 +17,7 @@ if config.use_tempfiles:
class Peer(object):
__slots__ = (
"ip", "port", "site", "key", "connection", "time_found", "time_response", "time_hashfield", "time_added",
"last_ping", "hashfield", "connection_error", "hash_failed", "download_bytes", "download_time"
"time_my_hashfield_sent", "last_ping", "hashfield", "connection_error", "hash_failed", "download_bytes", "download_time"
)
def __init__(self, ip, port, site=None):
@ -28,7 +28,8 @@ class Peer(object):
self.connection = None
self.hashfield = PeerHashfield() # Got optional files hash_id
self.time_hashfield = None # Last time hashfiled downloaded
self.time_hashfield = None # Last time peer's hashfiled downloaded
self.time_my_hashfield_sent = None # Last time my hashfield sent to peer
self.time_found = time.time() # Time of last found in the torrent tracker
self.time_response = None # Time of last successful response from peer
self.time_added = time.time()
@ -87,7 +88,7 @@ class Peer(object):
def found(self):
self.time_found = time.time()
# Send a command to peer
# Send a command to peer and return response value
def request(self, cmd, params={}, stream_to=None):
if not self.connection or self.connection.closed:
self.connect()
@ -239,6 +240,7 @@ class Peer(object):
return self.hashfield
# Find peers for hashids
# Return: {hash1: ["ip:port", "ip:port",...],...}
def findHashIds(self, hash_ids):
res = self.request("findHashIds", {"site": self.site.address, "hash_ids": hash_ids})
@ -246,6 +248,21 @@ class Peer(object):
return False
return {key: map(helper.unpackAddress, val) for key, val in res["peers"].iteritems()}
# Send my hashfield to peer
# Return: True if sent
def sendMyHashfield(self):
if self.connection and self.connection.handshake.get("rev", 0) < 510:
return False # Not supported
if self.time_my_hashfield_sent and self.site.content_manager.hashfield.time_changed <= self.time_my_hashfield_sent:
return False # Peer already has the latest hashfield
res = self.request("setHashfield", {"site": self.site.address, "hashfield_raw": self.site.content_manager.hashfield.tostring()})
if not res or "error" in res:
return False
else:
self.time_my_hashfield_sent = time.time()
return True
# Stop and remove from site
def remove(self):
self.log("Removing peer...Connection error: %s, Hash failed: %s" % (self.connection_error, self.hash_failed))

View file

@ -1,9 +1,11 @@
import array
import time
class PeerHashfield():
def __init__(self):
self.storage = self.createStoreage()
self.time_changed = time.time()
def createStoreage(self):
storage = array.array("H")
@ -17,23 +19,26 @@ class PeerHashfield():
def appendHash(self, hash):
hash_id = int(hash[0:4], 16)
if hash_id not in self:
self.append(hash_id)
if hash_id not in self.storage:
self.storage.append(hash_id)
self.time_changed = time.time()
return True
else:
return False
def appendHashId(self, hash_id):
if hash_id not in self:
self.append(hash_id)
if hash_id not in self.storage:
self.storage.append(hash_id)
self.time_changed = time.time()
return True
else:
return False
def removeHash(self, hash):
hash_id = int(hash[0:4], 16)
if hash_id in self:
self.remove(hash_id)
if hash_id in self.storage:
self.storage.remove(hash_id)
self.time_changed = time.time()
return True
else:
return False
@ -42,8 +47,20 @@ class PeerHashfield():
return int(hash[0:4], 16)
def hasHash(self, hash):
return int(hash[0:4], 16) in self
return int(hash[0:4], 16) in self.storage
def replaceFromString(self, hashfield_raw):
self.storage = self.createStoreage()
self.fromstring(hashfield_raw)
self.storage.fromstring(hashfield_raw)
self.time_changed = time.time()
if __name__ == "__main__":
field = PeerHashfield()
s = time.time()
for i in range(10000):
field.appendHashId(i)
print time.time()-s
s = time.time()
for i in range(10000):
field.hasHash("AABB")
print time.time()-s