[Core] Handle already prefetching magnet metadata

This commit is contained in:
Calum Lind 2018-09-25 11:41:15 +01:00
parent 759a618f74
commit 5a2990ff90
3 changed files with 31 additions and 4 deletions

View File

@ -419,11 +419,16 @@ class Core(component.Component):
The metadata is base64 encoded.
"""
def on_metadata(result):
def on_metadata(result, result_d):
torrent_id, metadata = result
return torrent_id, b64encode(metadata)
result_d.callback((torrent_id, b64encode(metadata)))
return result
return self.torrentmanager.prefetch_metadata(magnet, timeout).addCallback(on_metadata)
d = self.torrentmanager.prefetch_metadata(magnet, timeout)
# Use a seperate callback chain to handle existing prefetching magnet.
result_d = defer.Deferred()
d.addBoth(on_metadata, result_d)
return result_d
@export
def add_torrent_file(self, filename, filedump, options):

View File

@ -316,6 +316,11 @@ class TorrentManager(component.Component):
"""
torrent_id = get_magnet_info(magnet)['info_hash']
if torrent_id in self.prefetching_metadata:
d = self.prefetching_metadata[torrent_id][0]
return d
add_torrent_params = {}
add_torrent_params['save_path'] = gettempdir()
add_torrent_params['url'] = magnet.strip().encode('utf8')

View File

@ -11,7 +11,7 @@ from base64 import b64encode
from hashlib import sha1 as sha
import pytest
from twisted.internet import defer, reactor
from twisted.internet import defer, reactor, task
from twisted.internet.error import CannotListenError
from twisted.python.failure import Failure
from twisted.web.http import FORBIDDEN
@ -88,6 +88,8 @@ class CoreTestCase(BaseTestCase):
self.rpcserver = RPCServer(listen=False)
self.core = Core()
self.core.config.config['lsd'] = False
self.clock = task.Clock()
self.core.torrentmanager.callLater = self.clock.callLater
self.listen_port = 51242
return component.start().addCallback(self.start_web_server)
@ -311,6 +313,21 @@ class CoreTestCase(BaseTestCase):
r2 = self.core.get_torrent_status(tid2, ['paused'])
self.assertTrue(r2['paused'])
def test_prefetch_metadata_existing(self):
"""Check another call with same magnet returns existing deferred."""
magnet = 'magnet:?xt=urn:btih:ab570cdd5a17ea1b61e970bb72047de141bce173'
expected = ('ab570cdd5a17ea1b61e970bb72047de141bce173', '')
def on_result(result):
self.assertEqual(result, expected)
d = self.core.prefetch_magnet_metadata(magnet)
d.addCallback(on_result)
d2 = self.core.prefetch_magnet_metadata(magnet)
d2.addCallback(on_result)
self.clock.advance(30)
return defer.DeferredList([d, d2])
@defer.inlineCallbacks
def test_remove_torrent(self):
options = {}