2015-08-20 17:27:15 +02:00
|
|
|
import binascii
|
2016-11-03 20:42:45 +01:00
|
|
|
import logging
|
|
|
|
|
2015-08-20 17:27:15 +02:00
|
|
|
from zope.interface import implements
|
2017-02-16 05:38:33 +01:00
|
|
|
from twisted.internet import defer, reactor
|
2015-08-20 17:27:15 +02:00
|
|
|
from lbrynet.interfaces import IPeerFinder
|
2017-02-16 05:38:33 +01:00
|
|
|
from lbrynet.core.utils import short_hash
|
2015-08-20 17:27:15 +02:00
|
|
|
|
|
|
|
|
2016-11-03 20:42:45 +01:00
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
2015-08-20 17:27:15 +02:00
|
|
|
class DHTPeerFinder(object):
|
|
|
|
"""This class finds peers which have announced to the DHT that they have certain blobs"""
|
|
|
|
implements(IPeerFinder)
|
|
|
|
|
|
|
|
def __init__(self, dht_node, peer_manager):
|
|
|
|
self.dht_node = dht_node
|
|
|
|
self.peer_manager = peer_manager
|
|
|
|
self.peers = []
|
|
|
|
self.next_manage_call = None
|
|
|
|
|
|
|
|
def run_manage_loop(self):
|
|
|
|
self._manage_peers()
|
|
|
|
self.next_manage_call = reactor.callLater(60, self.run_manage_loop)
|
|
|
|
|
|
|
|
def stop(self):
|
2017-08-02 21:48:07 +02:00
|
|
|
log.info("Stopping DHT peer finder.")
|
2015-08-20 17:27:15 +02:00
|
|
|
if self.next_manage_call is not None and self.next_manage_call.active():
|
|
|
|
self.next_manage_call.cancel()
|
|
|
|
self.next_manage_call = None
|
|
|
|
|
|
|
|
def _manage_peers(self):
|
|
|
|
pass
|
|
|
|
|
2017-02-16 05:38:33 +01:00
|
|
|
@defer.inlineCallbacks
|
|
|
|
def find_peers_for_blob(self, blob_hash, timeout=None):
|
|
|
|
def _trigger_timeout():
|
|
|
|
if not finished_deferred.called:
|
2017-02-20 01:27:01 +01:00
|
|
|
log.debug("Peer search for %s timed out", short_hash(blob_hash))
|
2017-02-16 05:38:33 +01:00
|
|
|
finished_deferred.cancel()
|
|
|
|
|
2015-08-20 17:27:15 +02:00
|
|
|
bin_hash = binascii.unhexlify(blob_hash)
|
2017-02-16 05:38:33 +01:00
|
|
|
finished_deferred = self.dht_node.getPeersForBlob(bin_hash)
|
|
|
|
|
|
|
|
if timeout is not None:
|
|
|
|
reactor.callLater(timeout, _trigger_timeout)
|
|
|
|
|
|
|
|
peer_list = yield finished_deferred
|
|
|
|
|
|
|
|
peers = set(peer_list)
|
|
|
|
good_peers = []
|
|
|
|
for host, port in peers:
|
|
|
|
peer = self.peer_manager.get_peer(host, port)
|
|
|
|
if peer.is_available() is True:
|
|
|
|
good_peers.append(peer)
|
2015-08-20 17:27:15 +02:00
|
|
|
|
2017-02-16 05:38:33 +01:00
|
|
|
defer.returnValue(good_peers)
|
2015-08-20 17:27:15 +02:00
|
|
|
|
|
|
|
def get_most_popular_hashes(self, num_to_return):
|
2016-11-03 20:42:57 +01:00
|
|
|
return self.dht_node.get_most_popular_hashes(num_to_return)
|