def announce(self, file_name, peer_ref): if peer_ref not in self.index[file_name]: self.index[file_name].append( peer_ref) # First time announce, add member to swarm self.last_announces[ peer_ref.actor.url] = datetime.now() # Keep announce timestamp _print(self, "Subscribed: " + peer_ref.actor.url + " in: " + file_name)
def pull_callback(self, future): file_name = future.result()[0] chunk_id = future.result()[1] chunk_data = future.result()[2] if not chunk_data: return self.torrents[file_name].file.set_chunk(chunk_id, chunk_data) self.torrents[file_name].update() _print(self, "has pulled: ID:" + str(chunk_id) + " -> <" + chunk_data + "> for file: " + file_name)
def active_thread(self): for torrent in self.torrents.values(): if torrent.file.completed: continue # Torrent complete, ask for chunks of incomplete torrents for peer in torrent.peers: chunk_id = torrent.file.get_random_chunk_id() while torrent.file.chunk_map[ chunk_id]: # Loop until an empty chunk is found chunk_id = torrent.file.get_random_chunk_id() future = peer.pull(chunk_id, torrent.file.name, future=True) future.add_callback("pull_callback") _print( self, "asking for ID:" + str(chunk_id) + " to " + peer.actor.url + " for file: " + torrent.file.name)
def update_peers_callback(self, future): file_name = future.result()[0] peers = future.result()[1] if peers is None: return if self.proxy in peers: peers.remove(self.proxy) self.torrents[file_name].peers += peers # Sum up peers from all trackers self.torrents[file_name].peers = list(set(self.torrents[file_name].peers)) # Unique list _print(self, "knows these peers: " + str( map(lambda proxy: proxy.actor.url, self.torrents[file_name].peers)) + " for file: " + file_name)
def active_thread(self): # self.current_cycle += 1 for torrent in self.torrents.values(): retrieve(self.current_cycle, torrent.file.name, torrent.file.downloaded) if torrent.file.completed or not torrent.peers: continue # Torrent complete, ask for chunks of incomplete torrents peer = choice(torrent.peers) chunk_id = torrent.file.get_random_chunk_id() while torrent.file.chunk_map[chunk_id]: # Loop until an empty chunk is found chunk_id = torrent.file.get_random_chunk_id() future = peer.pull(chunk_id, torrent.file.name, future=True) future.add_callback("pull_callback") _print(self, "asking for ID:" + str(chunk_id) + " to " + peer.actor.url + " for file: " + torrent.file.name)
def active_thread(self): for torrent in self.torrents.values(): if torrent.file.downloaded == 0: continue # If peer has no content to disseminate from this torrent, try next one chunk_id = torrent.file.get_random_chunk_id() chunk_data = torrent.file.get_chunk(chunk_id) while not chunk_data: # Loop until valid chunk found chunk_id = torrent.file.get_random_chunk_id() chunk_data = torrent.file.get_chunk(chunk_id) for peer in torrent.peers: # Shares this chunk among known peers peer.push(chunk_id, chunk_data, torrent.file.name) _print( self, "pushing ID:" + str(chunk_id) + " <" + chunk_data + "> to " + peer.actor.url + " from file: " + torrent.file.name)
def active_thread(self): # self.current_cycle += 1 for torrent in self.torrents.values(): retrieve(self.current_cycle, torrent.file.name, torrent.file.downloaded) if torrent.file.downloaded == 0 or not torrent.peers: continue # If peer has no content to disseminate from this torrent, try next one chunk_id = torrent.file.get_random_chunk_id() chunk_data = torrent.file.get_chunk(chunk_id) while not chunk_data: # Loop until valid chunk found chunk_id = torrent.file.get_random_chunk_id() chunk_data = torrent.file.get_chunk(chunk_id) peer = choice(torrent.peers) peer.push(chunk_id, chunk_data, torrent.file.name) _print(self, "pushing ID:" + str( chunk_id) + " <" + chunk_data + "> to " + peer.actor.url + " from file: " + torrent.file.name)
def update(self): # Remove inactive peers from self.last_announces self.last_announces = { peer: timestamp for peer, timestamp in self.last_announces.items() if datetime.now() - timestamp <= timedelta(seconds=self.announce_timeout) } # Remove inactive peers from self.index for file_name, peers in self.index.items(): for peer in peers: if peer.actor.url not in self.last_announces: self.index[file_name].remove(peer) _print( self, "Unsubscribed: " + peer.actor.url + " of: " + file_name)