lbry-sdk/lbrynet/p2p/SinglePeerDownloader.py

110 lines
3.9 KiB
Python
Raw Normal View History

import logging
import shutil
import tempfile
2019-01-11 00:48:08 +01:00
from twisted.internet import defer, reactor
2019-01-11 00:14:57 +01:00
from lbrynet.extras.compat import d2f
2018-11-09 20:02:03 +01:00
from lbrynet.blob.blob_file import BlobFile
from lbrynet.p2p.BlobManager import DiskBlobManager
from lbrynet.p2p.RateLimiter import DummyRateLimiter
from lbrynet.p2p.PaymentRateManager import OnlyFreePaymentsManager
from lbrynet.p2p.client.BlobRequester import BlobRequester
from lbrynet.p2p.client.StandaloneBlobDownloader import StandaloneBlobDownloader
from lbrynet.p2p.client.ConnectionManager import ConnectionManager
from lbrynet.extras.daemon.storage import SQLiteStorage
2018-11-07 21:15:05 +01:00
from lbrynet.extras.daemon.PeerFinder import DummyPeerFinder
2019-01-21 21:55:50 +01:00
from lbrynet.conf import Config
2018-02-15 22:49:00 +01:00
log = logging.getLogger(__name__)
class SinglePeerFinder(DummyPeerFinder):
def __init__(self, peer):
super().__init__()
self.peer = peer
def find_peers_for_blob(self, blob_hash, timeout=None, filter_self=False):
return defer.succeed([self.peer])
class BlobCallback(BlobFile):
def __init__(self, blob_dir, blob_hash, timeout):
super().__init__(blob_dir, blob_hash)
self.callback = defer.Deferred()
reactor.callLater(timeout, self._cancel)
def _cancel(self):
if not self.callback.called:
self.callback.callback(False)
def save_verified_blob(self, writer):
result = BlobFile.save_verified_blob(self, writer)
if not self.callback.called:
self.callback.callback(True)
return result
class SingleBlobDownloadManager:
def __init__(self, blob):
self.blob = blob
def needed_blobs(self):
if self.blob.verified:
return []
else:
return [self.blob]
def get_head_blob_hash(self):
return self.blob.blob_hash
class SinglePeerDownloader:
2019-01-21 21:55:50 +01:00
def __init__(self, conf: Config):
self.conf = conf
self._payment_rate_manager = OnlyFreePaymentsManager()
self._rate_limiter = DummyRateLimiter()
self._wallet = None
self._blob_manager = None
def setup(self, wallet, blob_manager=None):
if not self._wallet:
self._wallet = wallet
if not self._blob_manager:
self._blob_manager = blob_manager
@defer.inlineCallbacks
def download_blob_from_peer(self, peer, timeout, blob_hash, blob_manager):
log.debug("Try to download %s from %s", blob_hash, peer.host)
blob_manager = blob_manager
blob = BlobCallback(blob_manager.blob_dir, blob_hash, timeout)
download_manager = SingleBlobDownloadManager(blob)
peer_finder = SinglePeerFinder(peer)
requester = BlobRequester(blob_manager, peer_finder, self._payment_rate_manager,
self._wallet, download_manager)
2019-01-21 21:55:50 +01:00
downloader = StandaloneBlobDownloader(self.conf, blob_hash, blob_manager, peer_finder,
self._rate_limiter, self._payment_rate_manager,
self._wallet, timeout=timeout)
info_exchanger = self._wallet.get_info_exchanger()
connection_manager = ConnectionManager(downloader, self._rate_limiter, [requester],
[info_exchanger])
connection_manager.start()
result = yield blob.callback
if not result:
log.debug("Failed to downloaded %s from %s", blob_hash[:16], peer.host)
2018-12-11 19:04:32 +01:00
yield connection_manager.stop()
defer.returnValue(result)
2019-01-11 00:14:57 +01:00
async def download_temp_blob_from_peer(self, peer, timeout, blob_hash):
2019-01-21 21:55:50 +01:00
tmp_storage = SQLiteStorage(Config(), ':memory:')
2019-01-11 00:14:57 +01:00
await tmp_storage.open()
tmp_dir = tempfile.mkdtemp()
tmp_blob_manager = DiskBlobManager(tmp_dir, tmp_storage)
try:
2019-01-11 00:14:57 +01:00
return await d2f(self.download_blob_from_peer(peer, timeout, blob_hash, tmp_blob_manager))
finally:
2019-01-11 00:14:57 +01:00
await tmp_storage.close()
shutil.rmtree(tmp_dir)